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