usermode/library/malloc-hoard-old/src/processheap.cpp

00001 
00002 //
00003 // The Hoard Multiprocessor Memory Allocator
00004 // www.hoard.org
00005 //
00006 // Author: Emery Berger, http://www.cs.utexas.edu/users/emery
00007 //
00008 // Copyright (c) 1998-2001, The University of Texas at Austin.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Library General Public License as
00012 // published by the Free Software Foundation, http://www.fsf.org.
00013 //
00014 // This library is distributed in the hope that it will be useful, but
00015 // WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Library General Public License for more details.
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   // The process heap is heap 0.
00042   setIndex (0);
00043   for (i = 0; i < MAX_HEAPS; i++) {
00044     // Set every thread's process heap to this one.
00045     theap[i].setpHeap (this);
00046     theap[i].setPersistentHeap (persistentHeap);
00047     // Set every thread heap's index.
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 // Print out statistics information.
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 // free (ptr, pheap):
00128 //   inputs: a pointer to an object allocated by malloc().
00129 //   side effects: returns the block to the object's superblock;
00130 //                 updates the thread heap's statistics;
00131 //                 may release the superblock to the process heap.
00132 
00133 void processHeap::free (void*)
00134 {
00135 // TODO: not sure yet whether we need a processHeap for allocation/free
00136 // in addition to persistentHeap
00137 #if 0
00138   // Return if ptr is 0.
00139   // This is the behavior prescribed by the standard.
00140   if (ptr == 0) {
00141     return;
00142   }
00143 
00144   // Find the block and superblock corresponding to this ptr.
00145 
00146   block * b = (block *) ptr - 1;
00147   assert (b->isValid());
00148 
00149   // Check to see if this block came from a memalign() call.
00150   if ((unsigned long) b->getNext() & 1) {
00151     // It did. Set the block to the actual block header.
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   // Return the block to the superblock,
00166   // find the heap that owns this superblock
00167   // and update its statistics.
00168   //
00169 
00170   hoardHeap * owner;
00171 
00172   // By acquiring the up lock on the superblock,
00173   // we prevent it from moving to the global heap.
00174   // This eventually pins it down in one heap,
00175   // so this loop is guaranteed to terminate.
00176   // (It should generally take no more than two iterations.)
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     // Suspend to allow ownership to quiesce.
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 }

Generated on Sat Apr 23 11:43:35 2011 for Mnemosyne by  doxygen 1.4.7