00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020
00021 #include "config.h"
00022
00023 #include "threadheap.h"
00024
00025 #include "processheap.h"
00026
00027
00028 processHeap::processHeap (void)
00029 : _buffer (NULL),
00030 _bufferCount (0)
00031 #if HEAP_FRAG_STATS
00032 , _currentAllocated (0),
00033 _currentRequested (0),
00034 _maxAllocated (0),
00035 _inUseAtMaxAllocated (0),
00036 _maxRequested (0)
00037 #endif
00038 {
00039 int i;
00040
00041 setIndex (0);
00042 for (i = 0; i < MAX_HEAPS; i++) {
00043
00044 theap[i].setpHeap (this);
00045
00046 theap[i].setIndex (i + 1);
00047 }
00048 #if HEAP_LOG
00049 for (i = 0; i < MAX_HEAPS + 1; i++) {
00050 char fname[255];
00051 sprintf (fname, "log%d", i);
00052 unlink (fname);
00053 _log[i].open (fname);
00054 }
00055 #endif
00056 #if HEAP_FRAG_STATS
00057 hoardLockInit (_statsLock);
00058 #endif
00059 hoardLockInit (_bufferLock);
00060 }
00061
00062
00063
00064 void processHeap::stats (void) {
00065 #if HEAP_STATS
00066 int umax = 0;
00067 int amax = 0;
00068 for (int j = 0; j < MAX_HEAPS; j++) {
00069 for (int i = 0; i < SIZE_CLASSES; i++) {
00070 amax += theap[j].maxAllocated(i) * sizeFromClass (i);
00071 umax += theap[j].maxInUse(i) * sizeFromClass (i);
00072 }
00073 }
00074 printf ("Amax <= %d, Umax <= %d\n", amax, umax);
00075 #if HEAP_FRAG_STATS
00076 amax = getMaxAllocated();
00077 umax = getMaxRequested();
00078 printf ("Maximum allocated = %d\nMaximum in use = %d\nIn use at max allocated = %d\n", amax, umax, getInUseAtMaxAllocated());
00079 printf ("Still in use = %d\n", _currentRequested);
00080 printf ("Fragmentation (3) = %f\n", (float) amax / (float) getInUseAtMaxAllocated());
00081 printf ("Fragmentation (4) = %f\n", (float) amax / (float) umax);
00082 #endif
00083
00084 #endif // HEAP_STATS
00085 #if HEAP_LOG
00086 printf ("closing logs.\n");
00087 fflush (stdout);
00088 for (int i = 0; i < MAX_HEAPS + 1; i++) {
00089 _log[i].close();
00090 }
00091 #endif
00092 }
00093
00094
00095
00096 #if HEAP_FRAG_STATS
00097 void processHeap::setAllocated (int requestedSize,
00098 int actualSize)
00099 {
00100 hoardLock (_statsLock);
00101 _currentRequested += requestedSize;
00102 _currentAllocated += actualSize;
00103 if (_currentRequested > _maxRequested) {
00104 _maxRequested = _currentRequested;
00105 }
00106 if (_currentAllocated > _maxAllocated) {
00107 _maxAllocated = _currentAllocated;
00108 _inUseAtMaxAllocated = _currentRequested;
00109 }
00110 hoardUnlock (_statsLock);
00111 }
00112
00113
00114 void processHeap::setDeallocated (int requestedSize,
00115 int actualSize)
00116 {
00117 hoardLock (_statsLock);
00118 _currentRequested -= requestedSize;
00119 _currentAllocated -= actualSize;
00120 hoardUnlock (_statsLock);
00121 }
00122 #endif
00123
00124
00125
00126
00127
00128
00129
00130
00131 void processHeap::free (void * ptr)
00132 {
00133
00134
00135
00136 if (ptr == 0) {
00137 return;
00138 }
00139
00140
00141
00142 block * b = (block *) ptr - 1;
00143 assert (b->isValid());
00144
00145
00146 if ((unsigned long) b->getNext() & 1) {
00147
00148 b = (block *) ((unsigned long) b->getNext() & ~1);
00149 assert (b->isValid());
00150 }
00151
00152 b->markFree();
00153
00154 superblock * sb = b->getSuperblock();
00155 assert (sb);
00156 assert (sb->isValid());
00157
00158 const int sizeclass = sb->getBlockSizeClass();
00159
00160
00161
00162
00163
00164
00165
00166 hoardHeap * owner;
00167
00168
00169
00170
00171
00172
00173 sb->upLock();
00174 for (;;) {
00175 owner = sb->getOwner();
00176 owner->lock();
00177 if (owner == sb->getOwner()) {
00178 break;
00179 } else {
00180 owner->unlock();
00181 }
00182
00183 hoardYield();
00184 }
00185
00186 #if HEAP_LOG
00187 MemoryRequest m;
00188 m.free (ptr);
00189 getLog (owner->getIndex()).append(m);
00190 #endif
00191 #if HEAP_FRAG_STATS
00192 setDeallocated (b->getRequestedSize(), 0);
00193 #endif
00194
00195 int sbUnmapped = owner->freeBlock (b, sb, sizeclass, this);
00196
00197 owner->unlock();
00198 if (!sbUnmapped) {
00199 sb->upUnlock();
00200 }
00201 }