usermode/library/malloc-original/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 
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   // The process heap is heap 0.
00041   setIndex (0);
00042   for (i = 0; i < MAX_HEAPS; i++) {
00043     // Set every thread's process heap to this one.
00044     theap[i].setpHeap (this);
00045     // Set every thread heap's index.
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 // Print out statistics information.
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 // free (ptr, pheap):
00126 //   inputs: a pointer to an object allocated by malloc().
00127 //   side effects: returns the block to the object's superblock;
00128 //                 updates the thread heap's statistics;
00129 //                 may release the superblock to the process heap.
00130 
00131 void processHeap::free (void * ptr)
00132 {
00133 
00134   // Return if ptr is 0.
00135   // This is the behavior prescribed by the standard.
00136   if (ptr == 0) {
00137     return;
00138   }
00139 
00140   // Find the block and superblock corresponding to this ptr.
00141 
00142   block * b = (block *) ptr - 1;
00143   assert (b->isValid());
00144 
00145   // Check to see if this block came from a memalign() call.
00146   if ((unsigned long) b->getNext() & 1) {
00147     // It did. Set the block to the actual block header.
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   // Return the block to the superblock,
00162   // find the heap that owns this superblock
00163   // and update its statistics.
00164   //
00165 
00166   hoardHeap * owner;
00167 
00168   // By acquiring the up lock on the superblock,
00169   // we prevent it from moving to the global heap.
00170   // This eventually pins it down in one heap,
00171   // so this loop is guaranteed to terminate.
00172   // (It should generally take no more than two iterations.)
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     // Suspend to allow ownership to quiesce.
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 }

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