2020-01-23 19:25:58 +08:00
|
|
|
// 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"
|
|
|
|
|
2020-03-17 00:34:08 +08:00
|
|
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
|
2020-01-23 19:25:58 +08:00
|
|
|
static bool CV_BUFFER_AREA_OVERRIDE_SAFE_MODE =
|
2020-03-17 00:34:08 +08:00
|
|
|
cv::utils::getConfigurationParameterBool("OPENCV_BUFFER_AREA_ALWAYS_SAFE", false);
|
|
|
|
#endif
|
2020-01-23 19:25:58 +08:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2020-03-17 00:34:08 +08:00
|
|
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
|
2020-01-23 19:25:58 +08:00
|
|
|
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);
|
|
|
|
}
|
2020-03-17 00:34:08 +08:00
|
|
|
#endif
|
2020-02-13 19:25:47 +08:00
|
|
|
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);
|
|
|
|
}
|
2020-01-23 19:25:58 +08:00
|
|
|
private:
|
|
|
|
void **ptr;
|
|
|
|
void * raw_mem;
|
|
|
|
size_t count;
|
|
|
|
ushort type_size;
|
|
|
|
ushort alignment;
|
|
|
|
};
|
|
|
|
|
|
|
|
//==================================================================================================
|
|
|
|
|
2020-03-17 00:34:08 +08:00
|
|
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
|
2020-01-23 19:25:58 +08:00
|
|
|
BufferArea::BufferArea(bool safe_) :
|
|
|
|
oneBuf(0),
|
|
|
|
totalSize(0),
|
|
|
|
safe(safe_ || CV_BUFFER_AREA_OVERRIDE_SAFE_MODE)
|
|
|
|
{
|
2020-03-17 00:34:08 +08:00
|
|
|
// nothing
|
2020-01-23 19:25:58 +08:00
|
|
|
}
|
2020-03-17 00:34:08 +08:00
|
|
|
#else
|
|
|
|
BufferArea::BufferArea(bool safe_)
|
|
|
|
{
|
|
|
|
CV_UNUSED(safe_);
|
|
|
|
}
|
|
|
|
#endif
|
2020-01-23 19:25:58 +08:00
|
|
|
|
|
|
|
BufferArea::~BufferArea()
|
|
|
|
{
|
2020-02-13 19:25:47 +08:00
|
|
|
release();
|
2020-01-23 19:25:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void BufferArea::allocate_(void **ptr, ushort type_size, size_t count, ushort alignment)
|
|
|
|
{
|
|
|
|
blocks.push_back(Block(ptr, type_size, count, alignment));
|
2020-03-17 00:34:08 +08:00
|
|
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
|
|
|
|
if (!safe)
|
|
|
|
{
|
2020-01-23 19:25:58 +08:00
|
|
|
totalSize += blocks.back().getByteCount();
|
2020-03-17 00:34:08 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
blocks.back().real_allocate();
|
|
|
|
}
|
2020-01-23 19:25:58 +08:00
|
|
|
}
|
|
|
|
|
2020-02-13 19:25:47 +08:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-23 19:25:58 +08:00
|
|
|
void BufferArea::commit()
|
|
|
|
{
|
2020-03-17 00:34:08 +08:00
|
|
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
|
2020-01-23 19:25:58 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2020-03-17 00:34:08 +08:00
|
|
|
#endif
|
2020-01-23 19:25:58 +08:00
|
|
|
}
|
|
|
|
|
2020-02-13 19:25:47 +08:00
|
|
|
void BufferArea::release()
|
|
|
|
{
|
|
|
|
for(std::vector<Block>::const_iterator i = blocks.begin(); i != blocks.end(); ++i)
|
|
|
|
{
|
|
|
|
i->cleanup();
|
|
|
|
}
|
|
|
|
blocks.clear();
|
2020-03-17 00:34:08 +08:00
|
|
|
#ifndef OPENCV_ENABLE_MEMORY_SANITIZER
|
2020-02-13 19:25:47 +08:00
|
|
|
if (oneBuf)
|
|
|
|
{
|
|
|
|
fastFree(oneBuf);
|
|
|
|
oneBuf = 0;
|
|
|
|
}
|
2020-03-17 00:34:08 +08:00
|
|
|
#endif
|
2020-02-13 19:25:47 +08:00
|
|
|
}
|
|
|
|
|
2020-01-23 19:25:58 +08:00
|
|
|
//==================================================================================================
|
|
|
|
|
|
|
|
}} // cv::utils::
|