Program Listing for File FrameMemory.cpp¶
↰ Return to documentation for file (lib/DataStructures/FrameMemory.cpp)
#include "DataStructures/FrameMemory.h"
#include "DataStructures/Frame.h"
namespace lsd_slam
{
FrameMemory::FrameMemory()
{
}
FrameMemory& FrameMemory::getInstance()
{
static FrameMemory theOneAndOnly;
return theOneAndOnly;
}
void FrameMemory::releaseBuffers()
{
boost::unique_lock<boost::mutex> lock(accessMutex);
int total = 0;
for(auto p : availableBuffers)
{
LOGF_IF(DEBUG, Conf().print.memoryDebugInfo, "deleting %d buffers of size %d!", (int)p.second.size(), (int)p.first);
total += p.second.size() * p.first;
for(unsigned int i=0;i<p.second.size();i++)
{
delete (char*)p.second[i];
bufferSizes.erase(p.second[i]);
}
p.second.clear();
}
availableBuffers.clear();
LOGF_IF(DEBUG, Conf().print.memoryDebugInfo, "released %.1f MB!", total / (1000000.0f));
}
void* FrameMemory::getBuffer(unsigned int sizeInByte)
{
boost::unique_lock<boost::mutex> lock(accessMutex);
if (availableBuffers.count(sizeInByte) > 0)
{
std::vector< void* >& availableOfSize = availableBuffers.at(sizeInByte);
if (availableOfSize.empty())
{
void* buffer = allocateBuffer(sizeInByte);
// assert(buffer != 0);
return buffer;
}
else
{
void* buffer = availableOfSize.back();
availableOfSize.pop_back();
// assert(buffer != 0);
return buffer;
}
}
else
{
void* buffer = allocateBuffer(sizeInByte);
// assert(buffer != 0);
return buffer;
}
}
float* FrameMemory::getFloatBuffer(unsigned int size)
{
return (float*)getBuffer(sizeof(float) * size);
}
void FrameMemory::returnBuffer(void* buffer)
{
if(buffer==0) return;
boost::unique_lock<boost::mutex> lock(accessMutex);
unsigned int size = bufferSizes.at(buffer);
//printf("returnFloatBuffer(%d)\n", size);
if (availableBuffers.count(size) > 0)
availableBuffers.at(size).push_back(buffer);
else
{
std::vector< void* > availableOfSize;
availableOfSize.push_back(buffer);
availableBuffers.insert(std::make_pair(size, availableOfSize));
}
}
void* FrameMemory::allocateBuffer(unsigned int size)
{
void* buffer = (void*)(new char[size]);
LOG_IF(DEBUG, Conf().print.memoryDebugInfo) << "Alloc " << size << " at " << std::ios::hex << buffer;
bufferSizes.insert(std::make_pair(buffer, size));
return buffer;
}
boost::shared_lock<boost::shared_mutex> FrameMemory::activateFrame(Frame* frame)
{
boost::unique_lock<boost::mutex> lock(activeFramesMutex);
if(frame->isActive)
activeFrames.remove(frame);
activeFrames.push_front(frame);
frame->isActive = true;
return boost::shared_lock<boost::shared_mutex>(frame->activeMutex);
}
void FrameMemory::deactivateFrame(Frame* frame)
{
boost::unique_lock<boost::mutex> lock(activeFramesMutex);
if(!frame->isActive) return;
activeFrames.remove(frame);
while(!frame->minimizeInMemory())
LOG(WARNING) << "cannot deactivateFrame frame " << frame->id()
<< ", as some active locks are lingering. May cause deadlock!"; // do it in a loop, to make sure it is really, really deactivated.
frame->isActive = false;
}
void FrameMemory::pruneActiveFrames()
{
boost::unique_lock<boost::mutex> lock(activeFramesMutex);
while((int)activeFrames.size() > maxLoopClosureCandidates + 20)
{
if(!activeFrames.back()->minimizeInMemory())
{
if(!activeFrames.back()->minimizeInMemory())
{
LOG(WARNING) << "failed to minimize frame " << activeFrames.back()->id() << " twice. maybe some active-lock is lingering?";
return; // pre-emptive return if could not deactivate.
}
}
activeFrames.back()->isActive = false;
activeFrames.pop_back();
}
}
}