00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef SST_CORE_MEMPOOL_H
00013 #define SST_CORE_MEMPOOL_H
00014
00015 #include <list>
00016 #include <deque>
00017
00018 #include <cstddef>
00019 #include <cstdlib>
00020 #include <cstring>
00021 #include <stdint.h>
00022 #include <sys/mman.h>
00023
00024 namespace SST {
00025 namespace Core {
00026
00027
00028
00029
00030 class MemPool
00031 {
00032 public:
00033
00034
00035
00036
00037 MemPool(size_t elementSize, size_t initialSize=(2<<20)) :
00038 numAlloc(0), numFree(0),
00039 elemSize(elementSize), arenaSize(initialSize)
00040 {
00041 allocPool();
00042 }
00043
00044 ~MemPool()
00045 {
00046 for ( std::list<uint8_t*>::iterator i = arenas.begin() ; i != arenas.end() ; ++i ) {
00047 ::free(*i);
00048 }
00049 }
00050
00051
00052 void* malloc()
00053 {
00054 if ( freeList.empty() ) {
00055 bool ok = allocPool();
00056 if ( !ok ) return NULL;
00057 }
00058 void *ret = freeList.back();
00059 freeList.pop_back();
00060 ++numAlloc;
00061 return ret;
00062 }
00063
00064
00065 void free(void *ptr)
00066 {
00067
00068 freeList.push_back(ptr);
00069
00070
00071
00072 ++numFree;
00073 }
00074
00075
00076
00077
00078
00079 uint64_t getBytesMemUsed() {
00080 uint64_t bytes_in_arenas = arenas.size() * arenaSize;
00081 uint64_t bytes_in_free_list = freeList.size() * sizeof(void*);
00082 return bytes_in_arenas + bytes_in_free_list;
00083 }
00084
00085 uint64_t getUndeletedEntries() {
00086 return numAlloc - numFree;
00087 }
00088
00089
00090 uint64_t numAlloc;
00091
00092 uint64_t numFree;
00093
00094 size_t getArenaSize() const { return arenaSize; }
00095 size_t getElementSize() const { return elemSize; }
00096
00097 const std::list<uint8_t*>& getArenas() { return arenas; }
00098
00099 private:
00100
00101 bool allocPool()
00102 {
00103 #if 0
00104 uint8_t *newPool = (uint8_t*)::malloc(arenaSize);
00105 #else
00106 uint8_t *newPool = (uint8_t*)mmap(0, arenaSize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
00107 if ( MAP_FAILED == newPool ) {
00108 return false;
00109 }
00110 #endif
00111 std::memset(newPool, 0xFF, arenaSize);
00112 arenas.push_back(newPool);
00113 size_t nelem = arenaSize / elemSize;
00114 for ( size_t i = 0 ; i < nelem ; i++ ) {
00115 uint32_t* ptr = (uint32_t*)(newPool + (elemSize*i));
00116
00117
00118
00119 freeList.push_back(ptr);
00120
00121 }
00122 return true;
00123 }
00124
00125 size_t elemSize;
00126 size_t arenaSize;
00127
00128 std::deque<void*> freeList;
00129 std::list<uint8_t*> arenas;
00130
00131 };
00132
00133 }
00134 }
00135
00136 #endif