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