16 void __stdcall
XERBLA (
const char* szSubName,
17 #ifdef CVM_PASS_STRING_LENGTH_TO_FTN_SUBROUTINES
20 const tint* pnParam)
throw (cvm::cvmexception)
27 #if !defined (CVM_STATIC) && (defined (_MSC_VER) || defined (__WATCOMC__))
29 # pragma managed(push, off)
32 BOOL APIENTRY DllMain (HANDLE ,
33 DWORD ul_reason_for_call,
36 switch (ul_reason_for_call)
38 case DLL_PROCESS_ATTACH:
39 case DLL_THREAD_ATTACH:
40 case DLL_THREAD_DETACH:
41 case DLL_PROCESS_DETACH:
54 #if !defined (CVM_STD_MUTEX)
57 CriticalSection::CriticalSection()
61 #if defined (WIN32) || defined (_WIN32)
62 #if defined (CVM_USE_CRITICAL_SECTION_NOT_MUTEX)
67 #else // POSIX Threads library assumed
68 mMutex(), mMutexAttr()
72 #if defined (WIN32) || defined (_WIN32)
73 # if defined (CVM_USE_CRITICAL_SECTION_NOT_MUTEX)
74 if (!::InitializeCriticalSectionAndSpinCount (&mCriticalSection, 0x80000400))
76 ::InitializeCriticalSection (&mCriticalSection);
80 mMutex = ::CreateMutex (
nullptr, FALSE,
nullptr);
81 mbOK = mMutex !=
nullptr;
84 if (pthread_mutexattr_init (&mMutexAttr) == 0 &&
85 pthread_mutexattr_setpshared (&mMutexAttr, PTHREAD_PROCESS_PRIVATE) == 0 &&
86 pthread_mutex_init (&mMutex, &mMutexAttr) == 0)
94 CriticalSection::~CriticalSection()
97 #if defined (WIN32) || defined (_WIN32)
100 # if defined (CVM_USE_CRITICAL_SECTION_NOT_MUTEX)
101 ::DeleteCriticalSection (&mCriticalSection);
103 ::CloseHandle(mMutex);
107 pthread_mutexattr_destroy (&mMutexAttr);
108 pthread_mutex_destroy (&mMutex);
113 void CriticalSection::enter()
119 #if defined (WIN32) || defined (_WIN32)
124 # if defined (CVM_USE_CRITICAL_SECTION_NOT_MUTEX)
125 ::EnterCriticalSection (&mCriticalSection);
127 ::WaitForSingleObject (mMutex, INFINITE);
130 if (!mbOK || pthread_mutex_lock (&mMutex) != 0)
138 void CriticalSection::leave()
144 #if defined (WIN32) || defined (_WIN32)
149 # if defined (CVM_USE_CRITICAL_SECTION_NOT_MUTEX)
150 ::LeaveCriticalSection (&mCriticalSection);
152 ::ReleaseMutex(mMutex);
155 if (!mbOK || pthread_mutex_unlock (&mMutex) != 0)
172 va_start (argList, nCause);
173 #if defined (CVM_VSNPRINTF_S_DEFINED)
179 if (nLength >= (
int)
sizeof(
mszMsg))
186 : std::exception(e), mnCause (e.mnCause)
188 #if defined (CVM_STRCPY_S_DEFINED)
196 #if defined (CVM_USE_POOL_MANAGER)
204 return gPool.Malloc (nBytes);
210 return gPool.AddRef (pD);
216 return gPool.Free (pD);
220 #define CVM_PAGE_SIZE (0x1000)
221 #define CVM_HEAP_SIZE ((tint) 0x40000000)
223 size_t _up_value (
size_t n)
225 if (n < CVM_PAGE_SIZE)
233 if (i && (n & ((1 << (i - 1)) - 1))) ++i;
239 MemoryPool::MemoryPool()
243 MemoryPool::~MemoryPool()
252 void MemoryPool::Clear()
254 std::for_each (mOutBlocks.rbegin(), mOutBlocks.rend(), MemoryPool::DeletePtr());
262 #if !defined (CVM_ALLOCATOR)
263 # define CVM_ALLOCATOR std::allocator
267 inline CVM_ALLOCATOR<T>& AllocatorInstance()
269 static CVM_ALLOCATOR<T> _A;
276 if (nBytes == 0)
return nullptr;
278 tbyte* pB = mMemoryBlocks.GetFreeBlock (nBytes);
282 const size_t nUpBytes = _up_value (nBytes);
283 const size_t nRest = nUpBytes - nBytes;
286 pB = AllocatorInstance<tbyte>().allocate(nUpBytes,
nullptr);
288 catch (
const std::bad_alloc&)
296 mOutBlocks.push_back (pB);
297 mMemoryBlocks.AddPair (pB, nBytes, nRest);
304 return mMemoryBlocks.AddRef (pD);
309 tint nRefCounter = mMemoryBlocks.FreeBlock (pToFree);
318 void MemoryBlocks::AddBlock (
tbyte* pBlock,
size_t nBytes,
bool bOccupied)
323 itr_Blocks i = mBlocks.upper_bound (pBlock);
324 itr_Blocks i_next = i;
326 if (i != mBlocks.end())
328 tbyte* pUpperBlock = (*i).first;
329 j = mFreeIt.find (pUpperBlock);
330 if (j != mFreeIt.end() && pBlock + nBytes == pUpperBlock)
332 nBytes += (*i).second.mnSize;
336 mFreeBs.erase ((*j).second);
341 if (i != mBlocks.begin() && mBlocks.size() > 0)
344 tbyte* pLowerBlock = (*i).first;
345 const size_t nLowerBytes = (*i).second.mnSize;
346 j = mFreeIt.find (pLowerBlock);
347 if (j != mFreeIt.end() && pLowerBlock + nLowerBytes == pBlock)
349 pBlock = pLowerBlock;
350 nBytes += nLowerBytes;
352 mFreeBs.erase ((*j).second);
356 mFreeIt[pBlock] = mFreeBs.insert (std::pair<tint, tbyte*>(nBytes, pBlock));
359 mBlocks.insert (std::pair<tbyte*, BlockProperty>(pBlock, BlockProperty(nBytes, 1)));
362 tint MemoryBlocks::FreeBlock (
tbyte* pBlock)
364 tint nRefCounter = 0;
365 itr_Blocks i = mBlocks.find (pBlock);
367 if (i != mBlocks.end())
369 if (mFreeIt.find (pBlock) == mFreeIt.end())
371 nRefCounter = -- (*i).second.mnRefCount;
372 if (nRefCounter <= 0)
374 const tint nBytes = (*i).second.mnSize;
376 AddBlock (pBlock, nBytes,
false);
382 assert (mFreeIt.find (pBlock) == mFreeIt.end());
394 tbyte* MemoryBlocks::GetFreeBlock (
size_t nBytes)
396 tbyte* pBlock =
nullptr;
397 if (mFreeBs.size() > 0)
400 itr_FreeBs i = mFreeBs.lower_bound (nBytes);
403 if (i != mFreeBs.end())
405 const size_t nRest = (*i).first - nBytes;
406 pBlock = (*i).second;
409 if (mFreeIt.size() > 0 && mFreeIt.find(pBlock) != mFreeIt.end())
411 mFreeIt.erase (pBlock);
413 if (mBlocks.size() > 0 && mBlocks.find(pBlock) != mBlocks.end())
415 mBlocks.erase (pBlock);
418 AddPair (pBlock, nBytes, nRest);
424 tbyte* MemoryBlocks::AddRef (
const tbyte* pcBlock)
427 itr_Blocks i = mBlocks.find (pBlock);
428 if (i != mBlocks.end())
430 ++ (*i).second.mnRefCount;
441 void MemoryBlocks::Assert (
const void* pvBlock,
size_t nBytes)
443 tbyte* pBlock = (
tbyte*) const_cast<void*>(pvBlock);
444 itr_Blocks i = mBlocks.find (pBlock);
445 if (i != mBlocks.end())
447 const size_t nSize = (*i).second.mnSize;
448 assert (nSize >= nBytes);
454 itr_Blocks end = mBlocks.end();
455 for (i = mBlocks.begin(); i != end; ++i)
458 nB = (*i).second.mnSize;
459 if (pBlock >= pB && pBlock < pB + nB)
461 tbyte* pBase = pB + nB;
462 tbyte* pTest = pBlock + nBytes;
463 assert (pTest <= pBase);
470 void MemoryBlocks::AddPair (
tbyte* pBlock,
size_t nBytes,
size_t nRest)
472 AddBlock (pBlock, nBytes,
true);
475 AddBlock (pBlock + nBytes, nRest,
false);
479 #endif // !CVM_USE_POOL_MANAGER
481 #if defined (CVM_USE_POOL_MANAGER) && defined (CVM_DEBUG)
482 CVM_API
void _cvm_assert (
const void* pvBlock,
size_t nBytes)
485 gPool.Assert (pvBlock, nBytes);
491 #endif // CVM_USE_POOL_MANAGER && CVM_DEBUG
495 #ifdef CVM_USE_POOL_MANAGER