usermode/library/malloc-original/src/processheap.h

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 /*
00022   processheap.h
00023   ------------------------------------------------------------------------
00024   We use one processHeap for the whole program.
00025   ------------------------------------------------------------------------
00026   @(#) $Id: processheap.h,v 1.84 2001/12/20 15:36:19 emery Exp $
00027   ------------------------------------------------------------------------
00028   Emery Berger                    | <http://www.cs.utexas.edu/users/emery>
00029   Department of Computer Sciences |             <http://www.cs.utexas.edu>
00030   University of Texas at Austin   |                <http://www.utexas.edu>
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   // Always grab at least this many superblocks' worth of memory which
00055   // we parcel out.
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   // Memory deallocation routines.
00067   void free (void * ptr);
00068 
00069   // Print out statistics information.
00070   void stats (void);
00071 
00072   // Get a thread heap index.
00073   inline int getHeapIndex (void);
00074 
00075   // Get the thread heap with index i.
00076   inline threadHeap& getHeap (int i);
00077 
00078   // Extract a superblock.
00079   inline superblock * acquire (const int c,
00080                                hoardHeap * dest);
00081 
00082   // Insert a superblock.
00083   inline void release (superblock * sb);
00084 
00085 #if HEAP_LOG
00086   // Get the log for index i.
00087   inline Log<MemoryRequest>& getLog (int i);
00088 #endif
00089 
00090 #if HEAP_FRAG_STATS
00091   // Declare that we have allocated an object.
00092   void setAllocated (int requestedSize,
00093                      int actualSize);
00094 
00095   // Declare that we have deallocated an object.
00096   void setDeallocated (int requestedSize,
00097                        int actualSize);
00098 
00099   // Return the number of wasted bytes at the high-water mark
00100   // (maxAllocated - maxRequested)
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   // Hide the lock & unlock methods.
00120 
00121   inline void lock (void) {
00122     hoardHeap::lock();
00123   }
00124 
00125   inline void unlock (void) {
00126     hoardHeap::unlock();
00127   }
00128 
00129   // Prevent copying and assignment.
00130   processHeap (const processHeap&);
00131   const processHeap& operator= (const processHeap&);
00132 
00133   // The per-thread heaps.
00134   threadHeap theap[MAX_HEAPS];
00135 
00136 #if HEAP_FRAG_STATS
00137   // Statistics required to compute fragmentation.  We cannot
00138   // unintrusively keep track of these on a multiprocessor, because
00139   // this would become a bottleneck.
00140 
00141   int _currentAllocated;
00142   int _currentRequested;
00143   int _maxAllocated;
00144   int _maxRequested;
00145   int _inUseAtMaxAllocated;
00146   int _fragmentation;
00147 
00148   // A lock to protect these statistics.
00149   hoardLockType _statsLock;
00150 #endif
00151 
00152 #if HEAP_LOG
00153   Log<MemoryRequest> _log[MAX_HEAPS + 1];
00154 #endif
00155 
00156   // A lock for the superblock buffer.
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 // Return ceil(log_2(num)).
00183 // num must be positive.
00184 static int lg (int num)
00185 {
00186   assert (num > 0);
00187   int power = 0;
00188   int n = 1;
00189   // Invariant: 2^power == n.
00190   while (n < num) {
00191     n <<= 1;
00192     power++;
00193   }
00194   return power;
00195 }
00196 
00197 
00198 // Hash out the thread id to a heap and return an index to that heap.
00199 int processHeap::getHeapIndex (void) {
00200 //  int tid = hoardGetThreadID() & hoardHeap::_numProcessorsMask;
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   // Remove the superblock with the most free space.
00213   superblock * maxSb = removeMaxSuperblock (sizeclass);
00214   if (maxSb) {
00215     maxSb->setOwner (dest);
00216   }
00217 
00218   unlock ();
00219 
00220   return maxSb;
00221 }
00222 
00223 
00224 // Put a superblock back into our list of superblocks.
00225 void processHeap::release (superblock * sb)
00226 {
00227   assert (EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
00228 
00229   lock();
00230 
00231   // Insert the superblock.
00232   insertSuperblock (sb->getBlockSizeClass(), sb, this);
00233 
00234   unlock();
00235 }
00236 
00237 
00238 #endif // _PROCESSHEAP_H_
00239 

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