mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.4 KiB
178 lines
4.4 KiB
// This file is part of OpenCV project. |
|
// It is subject to the license terms in the LICENSE file found in the top-level directory |
|
// of this distribution and at http://opencv.org/license.html. |
|
|
|
#include "opencv2/core/utils/buffer_area.private.hpp" |
|
#include "opencv2/core/utils/configuration.private.hpp" |
|
|
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER |
|
static bool CV_BUFFER_AREA_OVERRIDE_SAFE_MODE = |
|
cv::utils::getConfigurationParameterBool("OPENCV_BUFFER_AREA_ALWAYS_SAFE", false); |
|
#endif |
|
|
|
namespace cv { namespace utils { |
|
|
|
//================================================================================================== |
|
|
|
class BufferArea::Block |
|
{ |
|
private: |
|
inline size_t reserve_count() const |
|
{ |
|
return alignment / type_size - 1; |
|
} |
|
public: |
|
Block(void **ptr_, ushort type_size_, size_t count_, ushort alignment_) |
|
: ptr(ptr_), raw_mem(0), count(count_), type_size(type_size_), alignment(alignment_) |
|
{ |
|
CV_Assert(ptr && *ptr == NULL); |
|
} |
|
void cleanup() const |
|
{ |
|
CV_Assert(ptr && *ptr); |
|
*ptr = 0; |
|
if (raw_mem) |
|
fastFree(raw_mem); |
|
} |
|
size_t getByteCount() const |
|
{ |
|
return type_size * (count + reserve_count()); |
|
} |
|
void real_allocate() |
|
{ |
|
CV_Assert(ptr && *ptr == NULL); |
|
const size_t allocated_count = count + reserve_count(); |
|
raw_mem = fastMalloc(type_size * allocated_count); |
|
if (alignment != type_size) |
|
{ |
|
*ptr = alignPtr(raw_mem, alignment); |
|
CV_Assert(reinterpret_cast<size_t>(*ptr) % alignment == 0); |
|
CV_Assert(static_cast<uchar*>(*ptr) + type_size * count <= static_cast<uchar*>(raw_mem) + type_size * allocated_count); |
|
} |
|
else |
|
{ |
|
*ptr = raw_mem; |
|
} |
|
} |
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER |
|
void * fast_allocate(void * buf) const |
|
{ |
|
CV_Assert(ptr && *ptr == NULL); |
|
buf = alignPtr(buf, alignment); |
|
CV_Assert(reinterpret_cast<size_t>(buf) % alignment == 0); |
|
*ptr = buf; |
|
return static_cast<void*>(static_cast<uchar*>(*ptr) + type_size * count); |
|
} |
|
#endif |
|
bool operator==(void **other) const |
|
{ |
|
CV_Assert(ptr && other); |
|
return *ptr == *other; |
|
} |
|
void zeroFill() const |
|
{ |
|
CV_Assert(ptr && *ptr); |
|
memset(static_cast<uchar*>(*ptr), 0, count * type_size); |
|
} |
|
private: |
|
void **ptr; |
|
void * raw_mem; |
|
size_t count; |
|
ushort type_size; |
|
ushort alignment; |
|
}; |
|
|
|
//================================================================================================== |
|
|
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER |
|
BufferArea::BufferArea(bool safe_) : |
|
oneBuf(0), |
|
totalSize(0), |
|
safe(safe_ || CV_BUFFER_AREA_OVERRIDE_SAFE_MODE) |
|
{ |
|
// nothing |
|
} |
|
#else |
|
BufferArea::BufferArea(bool safe_) |
|
{ |
|
CV_UNUSED(safe_); |
|
} |
|
#endif |
|
|
|
BufferArea::~BufferArea() |
|
{ |
|
release(); |
|
} |
|
|
|
void BufferArea::allocate_(void **ptr, ushort type_size, size_t count, ushort alignment) |
|
{ |
|
blocks.push_back(Block(ptr, type_size, count, alignment)); |
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER |
|
if (!safe) |
|
{ |
|
totalSize += blocks.back().getByteCount(); |
|
} |
|
else |
|
#endif |
|
{ |
|
blocks.back().real_allocate(); |
|
} |
|
} |
|
|
|
void BufferArea::zeroFill_(void **ptr) |
|
{ |
|
for(std::vector<Block>::const_iterator i = blocks.begin(); i != blocks.end(); ++i) |
|
{ |
|
if (*i == ptr) |
|
{ |
|
i->zeroFill(); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
void BufferArea::zeroFill() |
|
{ |
|
for(std::vector<Block>::const_iterator i = blocks.begin(); i != blocks.end(); ++i) |
|
{ |
|
i->zeroFill(); |
|
} |
|
} |
|
|
|
void BufferArea::commit() |
|
{ |
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER |
|
if (!safe) |
|
{ |
|
CV_Assert(totalSize > 0); |
|
CV_Assert(oneBuf == NULL); |
|
CV_Assert(!blocks.empty()); |
|
oneBuf = fastMalloc(totalSize); |
|
void * ptr = oneBuf; |
|
for(std::vector<Block>::const_iterator i = blocks.begin(); i != blocks.end(); ++i) |
|
{ |
|
ptr = i->fast_allocate(ptr); |
|
} |
|
} |
|
#endif |
|
} |
|
|
|
void BufferArea::release() |
|
{ |
|
for(std::vector<Block>::const_iterator i = blocks.begin(); i != blocks.end(); ++i) |
|
{ |
|
i->cleanup(); |
|
} |
|
blocks.clear(); |
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER |
|
if (oneBuf) |
|
{ |
|
fastFree(oneBuf); |
|
oneBuf = 0; |
|
} |
|
#endif |
|
} |
|
|
|
//================================================================================================== |
|
|
|
}} // cv::utils::
|
|
|