7 #include "fwMemory/BufferManager.hpp" 9 #include "fwMemory/policy/NeverDump.hpp" 10 #include "fwMemory/stream/in/Buffer.hpp" 11 #include "fwMemory/stream/in/Raw.hpp" 13 #include <fwCom/Signal.hxx> 15 #include <fwCore/util/LazyInstantiator.hpp> 17 #include <fwThread/Worker.hpp> 19 #include <fwTools/System.hpp> 21 #include <boost/filesystem.hpp> 22 #include <boost/filesystem/fstream.hpp> 33 SPTR(
void) getLock( const BufferManager::sptr& manager, BufferManager::ConstBufferPtrType bufferPtr )
35 return manager->lockBuffer(bufferPtr).get();
42 return ::fwCore::util::LazyInstantiator< BufferManager >::getInstance();
47 BufferManager::BufferManager() :
48 m_updatedSig(UpdatedSignalType::New()),
49 m_dumpPolicy(::fwMemory::policy::NeverDump::New()),
50 m_loadingMode(BufferManager::DIRECT),
51 m_worker( ::fwThread::Worker::New() )
57 BufferManager::~BufferManager()
74 m_bufferInfos.insert( BufferInfoMapType::value_type( bufferPtr,
BufferInfo() ) );
75 m_updatedSig->asyncEmit();
89 auto& bufferInfo = m_bufferInfos[bufferPtr];
90 OSLM_ASSERT(
"There is still " << bufferInfo.lockCount() <<
" locks on this BufferObject (" <<
this <<
")",
91 bufferInfo.lockCounter.expired());
93 m_bufferInfos.erase(bufferPtr);
94 m_updatedSig->asyncEmit();
100 const ::fwMemory::BufferAllocationPolicy::sptr& policy)
108 const ::fwMemory::BufferAllocationPolicy::sptr& policy)
111 SLM_ASSERT(
"Buffer has already been allocated", info.
loaded && (*bufferPtr == NULL));
118 m_dumpPolicy->allocationRequest( info, bufferPtr, size );
122 policy->allocate(*bufferPtr, size);
130 info.istreamFactory =
131 std::make_shared< ::fwMemory::stream::in::Buffer >(*bufferPtr, size,
132 std::bind(&getLock, this->getSptr(), bufferPtr));
136 info.bufferPolicy = policy;
137 m_updatedSig->asyncEmit();
143 ::fwMemory::BufferManager::BufferType buffer,
145 const ::fwMemory::BufferAllocationPolicy::sptr& policy)
147 return m_worker->postTask<
void>(
154 SizeType size, const ::fwMemory::BufferAllocationPolicy::sptr& policy)
160 m_dumpPolicy->setRequest( info, bufferPtr, size );
171 info.bufferPolicy = policy;
172 info.fileFormat = ::fwMemory::OTHER;
174 info.istreamFactory =
175 std::make_shared< ::fwMemory::stream::in::Buffer >(*bufferPtr, size,
176 std::bind(&getLock, this->getSptr(), bufferPtr));
177 info.userStreamFactory =
false;
178 m_updatedSig->asyncEmit();
193 SLM_ASSERT(
"Buffer must be allocated or dumped", (*bufferPtr != NULL) || !info.
loaded);
195 m_dumpPolicy->reallocateRequest( info, bufferPtr, newSize );
201 info.bufferPolicy->reallocate(*bufferPtr, newSize);
210 m_updatedSig->asyncEmit();
214 info.istreamFactory =
215 std::make_shared< ::fwMemory::stream::in::Buffer>(*bufferPtr, newSize,
216 std::bind(&getLock, this->getSptr(), bufferPtr));
221 m_updatedSig->asyncEmit();
236 SLM_ASSERT(
"Buffer must be allocated or dumped", (*bufferPtr != NULL) || !info.
loaded);
238 m_dumpPolicy->destroyRequest( info, bufferPtr );
242 info.bufferPolicy->destroy(*bufferPtr);
247 m_updatedSig->asyncEmit();
253 BufferManager::BufferPtrType bufB)
265 std::swap(*bufA, *bufB);
266 std::swap(infoA.size, infoB.size);
268 std::swap(infoA.fsFile, infoB.fsFile);
269 std::swap(infoA.bufferPolicy, infoB.bufferPolicy);
270 std::swap(infoA.istreamFactory, infoB.istreamFactory);
271 std::swap(infoA.userStreamFactory, infoB.userStreamFactory);
280 AutoUnlock(
const BufferManager::sptr& manager, BufferManager::ConstBufferPtrType bufferPtr,
283 m_bufferPtr(bufferPtr)
287 bool restored = manager->restoreBuffer( bufferPtr ).get();
288 OSLM_ASSERT(
"restore not OK ( "<< restored <<
" && " << *bufferPtr <<
" != 0 ).",
289 restored && *bufferPtr != 0 );
290 FwCoreNotUsedMacro(restored);
298 m_manager->unlockBuffer(m_bufferPtr);
300 catch(std::exception& e)
310 BufferManager::sptr m_manager;
311 BufferManager::ConstBufferPtrType m_bufferPtr;
323 BufferManager::BufferPtrType castedBuffer =
const_cast< BufferManager::BufferPtrType
>(bufferPtr);
324 BufferInfo& info = m_bufferInfos[castedBuffer];
326 m_dumpPolicy->lockRequest( info, castedBuffer );
328 SPTR(
void) counter = info.lockCounter.lock();
331 counter = std::make_shared< AutoUnlock >( this->getSptr(), bufferPtr, info);
332 info.lockCounter = counter;
335 m_lastAccess.modified();
337 m_updatedSig->asyncEmit();
354 m_dumpPolicy->unlockRequest( info, bufferPtr );
356 m_updatedSig->asyncEmit();
371 BufferManager::BufferPtrType castedBuffer =
const_cast< BufferManager::BufferPtrType
>(bufferPtr);
372 BufferInfo& info = m_bufferInfos[castedBuffer];
380 if ( !info.
loaded || info.lockCount() > 0 || info.size == 0 )
386 ::boost::filesystem::path dumpedFile = ::boost::filesystem::unique_path( tmp/
"fwMemory-%%%%-%%%%-%%%%-%%%%.raw" );
388 OSLM_TRACE(
"dumping " << bufferPtr <<
" " << dumpedFile);
389 info.lockCounter.reset();
394 info.fileFormat = ::fwMemory::RAW;
395 info.istreamFactory = std::make_shared< ::fwMemory::stream::in::Raw >(info.fsFile);
396 info.userStreamFactory =
false;
397 info.bufferPolicy->destroy(*bufferPtr);
401 m_dumpPolicy->dumpSuccess( info, bufferPtr );
403 m_updatedSig->asyncEmit();
420 BufferManager::BufferPtrType castedBuffer =
const_cast< BufferManager::BufferPtrType
>(bufferPtr);
421 BufferInfo& info = m_bufferInfos[castedBuffer];
428 BufferManager::BufferPtrType bufferPtr, BufferManager::SizeType allocSize)
431 allocSize = ((allocSize) ? allocSize : info.size);
436 info.bufferPolicy->allocate(*bufferPtr, allocSize);
438 char* charBuf =
static_cast< char*
>(*bufferPtr);
439 SizeType size = std::min(allocSize, info.size);
440 bool notFailed =
false;
442 SPTR(std::istream) isptr = (*info.istreamFactory)();
443 std::istream& is = *isptr;
444 SizeType read = is.read(charBuf, size).gcount();
446 FW_RAISE_IF(
" Bad file size, expected: " << size <<
", was: " << read, size - read != 0);
447 notFailed = !is.fail();
456 m_dumpPolicy->restoreSuccess( info, bufferPtr );
458 info.fileFormat = ::fwMemory::OTHER;
460 = std::make_shared< ::fwMemory::stream::in::Buffer >(*bufferPtr,
462 std::bind(&getLock, this->getSptr(),
464 info.userStreamFactory =
false;
465 m_updatedSig->asyncEmit();
476 SizeType size, ::boost::filesystem::path& path)
484 SizeType size, ::boost::filesystem::path& path)
486 ::boost::filesystem::ofstream fs(path, std::ios::binary|std::ios::trunc);
487 FW_RAISE_IF(
"Memory management : Unable to open " << path, !fs.good());
488 const char* charBuf =
static_cast< const char*
>(buffer);
490 fs.write(charBuf, size);
498 ::boost::filesystem::path& path)
507 ::boost::filesystem::ifstream fs(path, std::ios::in|std::ios::binary|std::ios::ate);
508 FW_RAISE_IF(
"Unable to read " << path, !fs.good());
510 std::streampos fileSize = fs.tellg();
511 fs.seekg(0, std::ios::beg);
513 FW_RAISE_IF(path <<
": Bad file size, expected: " << size <<
", was: " << fileSize,
514 size - fileSize != 0);
517 char* charBuf =
static_cast< char*
>(buffer);
518 fs.read(charBuf, size);
535 std::stringstream sstr(
"");
536 sstr <<
"nb Elem = " << m_bufferInfos.size() << std::endl;
537 sstr << std::setw(18) <<
"Buffer" <<
"->" << std::setw(18) <<
"Address" <<
" " 538 << std::setw(10) <<
"Size" <<
" " 539 << std::setw(18) <<
"Policy" <<
" " 540 << std::setw(6) <<
"Access" <<
" " 541 << std::setw(4) <<
"Lock" <<
" " 542 <<
"DumpStatus" <<
" " 545 for( BufferInfoMapType::value_type item : m_bufferInfos )
548 sstr << std::setw(18) << item.first <<
"->" << std::setw(18) << *(item.first) <<
" " 549 << std::setw(10) << info.size <<
" " 550 << std::setw(18) << info.bufferPolicy <<
" " 551 << std::setw(6) << info.lastAccess <<
" " 552 << std::setw(4) << info.lockCount() <<
" " 553 << ((info.
loaded) ?
" " :
"not") <<
" loaded " 554 << ::boost::filesystem::path(info.fsFile) <<
" " 564 m_dumpPolicy = policy;
586 return m_bufferInfos;
594 std::bind(&BufferManager::computeBufferStats, m_bufferInfos) );
602 for(
const BufferInfoMapType::value_type& item : bufferInfo )
607 stats.totalDumped += info.size;
609 stats.totalManaged += info.size;
616 std::shared_future<void> BufferManager::setIStreamFactory(BufferPtrType bufferPtr,
620 ::fwMemory::FileFormatType format,
621 const ::fwMemory::BufferAllocationPolicy::sptr& policy
624 return m_worker->postTask<
void>(
634 ::fwMemory::FileFormatType format,
635 const ::fwMemory::BufferAllocationPolicy::sptr& policy
638 BufferInfoMapType::iterator iterInfo = m_bufferInfos.find(bufferPtr);
639 FW_RAISE_IF(
"Buffer is not managed by fwMemory::BufferManager.", iterInfo == m_bufferInfos.end() );
642 SLM_ASSERT(
"Buffer is already set", *bufferPtr == NULL && info.loaded);
644 m_dumpPolicy->setRequest( info, bufferPtr, size );
646 info.istreamFactory = factory;
647 info.userStreamFactory =
true;
649 info.fsFile = fsFile;
650 info.fileFormat = format;
651 info.bufferPolicy = policy;
654 m_dumpPolicy->dumpSuccess( info, bufferPtr );
656 switch(m_loadingMode)
658 case BufferManager::DIRECT:
661 case BufferManager::LAZY:
662 m_updatedSig->asyncEmit();
671 std::shared_future<BufferManager::StreamInfo>
683 BufferInfoMapType::const_iterator iterInfo = m_bufferInfos.find(bufferPtr);
684 FW_RAISE_IF(
"Buffer is not managed by fwMemory::BufferManager.", iterInfo == m_bufferInfos.end() );
686 streamInfo.size = info.size;
687 streamInfo.
fsFile = info.fsFile;
688 streamInfo.
format = info.fileFormat;
689 streamInfo.
userStream = info.userStreamFactory;
691 if(info.istreamFactory)
693 streamInfo.stream = (*info.istreamFactory)();
701 BufferManager::LoadingModeType BufferManager::getLoadingMode()
const 703 return m_loadingMode;
708 void BufferManager::setLoadingMode(LoadingModeType mode)
710 m_loadingMode = mode;
virtual void registerBufferImpl(BufferPtrType bufferPtr)
BufferManager'a Implementation.
::fwMemory::FileFormatType format
format of the dumped file
FWMEMORY_API void setDumpPolicy(const std::shared_ptr< ::fwMemory::IPolicy > &policy)
Sets the dump policy.
virtual std::string toStringImpl() const
BufferManager'a Implementation.
void setIStreamFactoryImpl(BufferPtrType bufferPtr, const std::shared_ptr< ::fwMemory::stream::in::IFactory > &factory, SizeType size,::fwMemory::FileHolder fsFile,::fwMemory::FileFormatType format, const ::fwMemory::BufferAllocationPolicy::sptr &policy)
BufferManager'a Implementation.
FWMEMORY_API std::shared_future< BufferStats > getBufferStats() const
Returns managed buffers statistics.
virtual void reallocateBufferImpl(BufferPtrType bufferPtr, SizeType newSize)
BufferManager'a Implementation.
StreamInfo getStreamInfoImpl(const ConstBufferPtrType bufferPtr) const
BufferManager'a Implementation.
virtual bool unlockBufferImpl(ConstBufferPtrType bufferPtr)
BufferManager'a Implementation.
bool readBufferImpl(BufferType buffer, SizeType size,::boost::filesystem::path &path)
BufferManager'a Implementation.
#define OSLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
The namespace fwMemory contains tools to manage memory. Use for dump.
BufferInfoMapType getBufferInfosImpl() const
BufferManager'a Implementation.
virtual FWMEMORY_API std::shared_future< std::shared_ptr< void > > lockBuffer(ConstBufferPtrType bufferPtr)
Hook called when a BufferObject is locked.
virtual FWMEMORY_API std::shared_future< std::string > toString() const
returns BufferManager status string
static FWMEMORY_API BufferManager::sptr getDefault()
Returns the current BufferManager instance.
virtual FWMEMORY_API std::shared_future< void > unregisterBuffer(BufferPtrType bufferPtr)
Hook called when a BufferObject is destroyed.
FWMEMORY_API std::shared_future< bool > readBuffer(BufferType buffer, SizeType size,::boost::filesystem::path &path)
Write/read a buffer.
bool restoreBufferImpl(ConstBufferPtrType buffer)
BufferManager'a Implementation.
#define OSLM_TRACE(message)
bool loaded
true if 'buffer' is loaded
virtual void unregisterBufferImpl(BufferPtrType bufferPtr)
BufferManager'a Implementation.
FWMEMORY_API std::shared_ptr< ::fwMemory::IPolicy > getDumpPolicy() const
Returns the dump policy.
virtual FWMEMORY_API std::shared_future< bool > unlockBuffer(ConstBufferPtrType bufferPtr)
Hook called when a BufferObject lock is released.
Contains fwAtomsFilter::factory utilities.
FWMEMORY_API std::shared_future< StreamInfo > getStreamInfo(const ConstBufferPtrType bufferPtr) const
Returns stream info.
virtual FWMEMORY_API std::shared_future< void > swapBuffer(BufferPtrType bufA, BufferPtrType bufB)
Hook called when a request to swap two BufferObject contents is made.
virtual FWMEMORY_API std::shared_future< void > destroyBuffer(BufferPtrType bufferPtr)
Hook called when a destruction is requested from a BufferObject.
virtual std::shared_ptr< void > lockBufferImpl(ConstBufferPtrType bufferPtr)
BufferManager'a Implementation.
bool userStream
true if stream has been set by the user
bool writeBufferImpl(ConstBufferType buffer, SizeType size,::boost::filesystem::path &path)
BufferManager'a Implementation.
virtual FWMEMORY_API std::shared_future< void > allocateBuffer(BufferPtrType bufferPtr, SizeType size, const ::fwMemory::BufferAllocationPolicy::sptr &policy)
Hook called when an allocation is requested from a BufferObject.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
bool dumpBufferImpl(ConstBufferPtrType buffer)
BufferManager'a Implementation.
BufferManager implementation.
FWMEMORY_API std::shared_future< BufferInfoMapType > getBufferInfos() const
Returns the Buffer info map.
virtual void destroyBufferImpl(BufferPtrType bufferPtr)
BufferManager'a Implementation.
virtual FWMEMORY_API std::shared_future< void > setBuffer(BufferPtrType bufferPtr,::fwMemory::BufferManager::BufferType buffer, SizeType size, const ::fwMemory::BufferAllocationPolicy::sptr &policy)
Hook called when a request is made to set BufferObject's buffer from an external buffer.
Implements an exception class for fwMemory.
virtual void setBufferImpl(BufferPtrType bufferPtr,::fwMemory::BufferManager::BufferType buffer, SizeType size, const ::fwMemory::BufferAllocationPolicy::sptr &policy)
BufferManager'a Implementation.
FWMEMORY_API std::shared_future< bool > writeBuffer(ConstBufferType buffer, SizeType size,::boost::filesystem::path &path)
Write/read a buffer.
virtual FWMEMORY_API std::shared_future< void > registerBuffer(BufferPtrType bufferPtr)
Hook called when a new BufferObject is created.
FWMEMORY_API std::shared_future< bool > restoreBuffer(ConstBufferPtrType bufferPtr)
Dump/restore a buffer.
FWCORE_API void modified()
Increment global Logical counter and copy it to this LogicStamp.
virtual void allocateBufferImpl(BufferPtrType bufferPtr, SizeType size, const ::fwMemory::BufferAllocationPolicy::sptr &policy)
BufferManager'a Implementation.
virtual void swapBufferImpl(BufferPtrType bufA, BufferPtrType bufB)
BufferManager'a Implementation.
FWMEMORY_API std::shared_future< bool > dumpBuffer(ConstBufferPtrType bufferPtr)
Dump/restore a buffer.
::fwMemory::FileHolder fsFile
path of the file containing the dumped buffer
virtual FWMEMORY_API std::shared_future< void > reallocateBuffer(BufferPtrType bufferPtr, SizeType newSize)
Hook called when a reallocation is requested from a BufferObject.