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