1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
// Geometric Tools, LLC
// Copyright (c) 1998-2014
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
//
// File Version: 5.0.3 (2010/09/19)
#include "Wm5CorePCH.h"
#include "Wm5Memory.h"
#ifdef WM5_USE_MEMORY
using namespace Wm5;
// The msMutex is used to prevent concurrent access to msMap. However, the
// order of declaration and initialization is as shown because the function
// CreateBlock tests msMap first to warn about pre-main allocations.
Memory::MemoryMap* Memory::msMap = 0;
Mutex Memory::msMutex;
Memory::Allocator Memory::msAllocator = &Memory::DefaultAllocator;
Memory::Deallocator Memory::msDeallocator = &Memory::DefaultDeallocator;
unsigned int Memory::Information::msUniqueID = 0;
//----------------------------------------------------------------------------
void Memory::Initialize (Allocator allocator, Deallocator deallocator)
{
msMutex.Enter();
msAllocator = allocator;
msDeallocator = deallocator;
// You must use 'new', not 'new0', otherwise you have an infinite
// loop trying to allocate msMap (over and over and over...).
assertion(msMap == 0, "The map already exists. Did you call"
" Memory::Initialize twice in a row?\n");
if (msMap == 0)
{
msMap = new MemoryMap();
}
msMutex.Leave();
}
//----------------------------------------------------------------------------
void Memory::Terminate (const std::string& filename)
{
msMutex.Enter();
assertion(msMap != 0, "The map does not exist. Did you call"
"Memory::Terminate twice in a row?\n");
if (!msMap)
{
msMutex.Leave();
return;
}
FILE* outFile = fopen(filename.c_str(), "wt");
if (!outFile)
{
msMutex.Leave();
return;
}
// Create a sorted map from the memory map based on unique ID.
SortedMap sorted;
MemoryMap::const_iterator mapIter = msMap->begin();
MemoryMap::const_iterator mapEnd = msMap->end();
for (/**/; mapIter != mapEnd; ++mapIter)
{
sorted[mapIter->second.mUniqueID] =
std::make_pair(mapIter->first, mapIter->second);
}
// Create the format for the output.
std::string format = "uid = %8u , ";
format += "addr = %p , ";
format += "numbytes = %13d , ";
format += "numdims = %d , ";
format += "%s (%4d)\n";
// Save the sorted map to disk.
SortedMap::const_iterator sortedIter = sorted.begin();
SortedMap::const_iterator sortedEnd = sorted.end();
for (/**/; sortedIter != sortedEnd; ++sortedIter)
{
unsigned int uniqueID = sortedIter->first;
void* address = sortedIter->second.first;
Information info = sortedIter->second.second;
fprintf(outFile, format.c_str(), uniqueID, address, info.mNumBytes,
info.mNumDimensions, info.mFile, info.mLine);
}
fclose(outFile);
// You must use 'delete', not 'delete0'. See the comments in the
// Memory::Initialize functoin.
delete msMap;
msMap = 0;
msMutex.Leave();
}
//----------------------------------------------------------------------------
void* Memory::CreateBlock (size_t numBytes, int numDimensions) const
{
msMutex.Enter();
void* memBlock = msAllocator(numBytes, mFile, mLine);
(*msMap)[memBlock] = Information(numBytes, numDimensions, mFile, mLine);
msMutex.Leave();
return memBlock;
}
//----------------------------------------------------------------------------
void* Memory::DefaultAllocator (size_t numBytes, const char*, int)
{
return malloc(numBytes);
}
//----------------------------------------------------------------------------
void Memory::DefaultDeallocator (void* memBlock, const char*, int)
{
free(memBlock);
}
//----------------------------------------------------------------------------
#endif
|