00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00052
00061 #ifndef _PERSISTENTHEAP_H_
00062 #define _PERSISTENTHEAP_H_
00063
00064 #include "config.h"
00065
00066 #include <stdio.h>
00067
00068 #include "arch-specific.h"
00069 #include "hoardheap.h"
00070 #include "threadheap.h"
00071
00072 #if HEAP_LOG
00073 #include "memstat.h"
00074 #include "log.h"
00075 #endif
00076
00077
00078
00079 enum {PERSISTENTHEAP_HEADER_BASE = 0xa00000000};
00080 enum {PERSISTENTHEAP_BASE = 0xb00000000};
00081 enum {PERSISTENTSUPERBLOCK_NUM = (128*1024)};
00082 #define PERSISTENTHEAP_SIZE ((uint64_t) PERSISTENTSUPERBLOCK_NUM * SUPERBLOCK_SIZE)
00083
00084 class persistentHeap : public hoardHeap {
00085
00086 public:
00087
00088
00089
00090 enum { REFILL_NUMBER_OF_SUPERBLOCKS = 16 };
00091
00092 persistentHeap (void);
00093
00094 ~persistentHeap (void) {
00095 #if HEAP_STATS
00096 stats();
00097 #endif
00098 }
00099
00100
00101 void format (void);
00102
00103
00104 void free (void * ptr);
00105
00106
00107 void stats (void);
00108
00109
00110 inline int getHeapIndex (void);
00111
00112
00113 inline threadHeap& getHeap (int i);
00114
00115
00116 inline superblock * acquire (const int c,
00117 hoardHeap * dest);
00118
00119
00120 inline void release (superblock * sb);
00121
00122 void scavenge();
00123
00124 #if HEAP_LOG
00125
00126 inline Log<MemoryRequest>& getLog (int i);
00127 #endif
00128
00129 #if HEAP_FRAG_STATS
00130
00131 void setAllocated (int requestedSize,
00132 int actualSize);
00133
00134
00135 void setDeallocated (int requestedSize,
00136 int actualSize);
00137
00138
00139
00140 inline int getFragmentation (void);
00141
00142 int getMaxAllocated (void) {
00143 return _maxAllocated;
00144 }
00145
00146 int getInUseAtMaxAllocated (void) {
00147 return _inUseAtMaxAllocated;
00148 }
00149
00150 int getMaxRequested (void) {
00151 return _maxRequested;
00152 }
00153
00154 #endif
00155 void *getPersistentSegmentBase()
00156 {
00157 return _psegmentBase;
00158 }
00159
00160
00161 static size_t objectSize (void * ptr);
00162 private:
00163
00164
00165
00166 inline void lock (void) {
00167 hoardHeap::lock();
00168 }
00169
00170 inline void unlock (void) {
00171 hoardHeap::unlock();
00172 }
00173
00174
00175 persistentHeap (const persistentHeap&);
00176 const persistentHeap& operator= (const persistentHeap&);
00177
00178
00179 threadHeap theap[MAX_HEAPS];
00180
00181 #if HEAP_FRAG_STATS
00182
00183
00184
00185
00186 int _currentAllocated;
00187 int _currentRequested;
00188 int _maxAllocated;
00189 int _maxRequested;
00190 int _inUseAtMaxAllocated;
00191 int _fragmentation;
00192
00193
00194 hoardLockType _statsLock;
00195 #endif
00196
00197 #if HEAP_LOG
00198 Log<MemoryRequest> _log[MAX_HEAPS + 1];
00199 #endif
00200
00201
00202 hoardLockType _bufferLock;
00203
00204 char * _buffer;
00205 int _bufferCount;
00206
00207
00208 void *_psegmentBase;
00209 };
00210
00211
00212 threadHeap& persistentHeap::getHeap (int i)
00213 {
00214 assert (i >= 0);
00215 assert (i < MAX_HEAPS);
00216 return theap[i];
00217 }
00218
00219
00220 #if HEAP_LOG
00221 Log<MemoryRequest>& persistentHeap::getLog (int i)
00222 {
00223 assert (i >= 0);
00224 assert (i < MAX_HEAPS + 1);
00225 return _log[i];
00226 }
00227 #endif
00228
00229
00230
00231 int persistentHeap::getHeapIndex (void) {
00232
00233 int tid = hoardGetThreadID() & MAX_HEAPS_MASK;
00234 assert (tid < MAX_HEAPS);
00235 return tid;
00236 }
00237
00238
00239 superblock * persistentHeap::acquire (const int sizeclass,
00240 hoardHeap * dest)
00241 {
00242 lock ();
00243
00244
00245 superblock * maxSb = removeMaxSuperblock (sizeclass);
00246 if (maxSb) {
00247 maxSb->setOwner (dest);
00248 }
00249
00250 unlock ();
00251
00252 return maxSb;
00253 }
00254
00255
00256
00257
00258 void persistentHeap::release (superblock *sb)
00259 {
00260 assert (EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
00261
00262 lock();
00263
00264
00265 insertSuperblock (sb->getBlockSizeClass(), sb, this);
00266
00267 unlock();
00268 }
00269
00270
00271
00272
00273 #endif // _PERSISTENTHEAP_H_
00274