usermode/library/malloc-hoard-old/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 persistentHeap;
00051 
00052 class processHeap : public hoardHeap {
00053 
00054 public:
00055 
00056   // Always grab at least this many superblocks' worth of memory which
00057   // we parcel out.
00058   enum { REFILL_NUMBER_OF_SUPERBLOCKS = 16 };
00059 
00060   processHeap (persistentHeap *persistentHeap);
00061 
00062   ~processHeap (void) {
00063 #if HEAP_STATS
00064     stats();
00065 #endif
00066   }
00067 
00068   // Memory deallocation routines.
00069   void free (void * ptr);
00070 
00071   // Print out statistics information.
00072   void stats (void);
00073 
00074   // Get a thread heap index.
00075   inline int getHeapIndex (void);
00076 
00077   // Get the thread heap with index i.
00078   inline threadHeap& getHeap (int i);
00079 
00080   // Extract a superblock.
00081   inline superblock * acquire (const int c,
00082                                hoardHeap * dest);
00083 
00084   // Insert a superblock.
00085   inline void release (superblock * sb);
00086 
00087 #if HEAP_LOG
00088   // Get the log for index i.
00089   inline Log<MemoryRequest>& getLog (int i);
00090 #endif
00091 
00092 #if HEAP_FRAG_STATS
00093   // Declare that we have allocated an object.
00094   void setAllocated (int requestedSize,
00095                      int actualSize);
00096 
00097   // Declare that we have deallocated an object.
00098   void setDeallocated (int requestedSize,
00099                        int actualSize);
00100 
00101   // Return the number of wasted bytes at the high-water mark
00102   // (maxAllocated - maxRequested)
00103   inline int getFragmentation (void);
00104 
00105   int getMaxAllocated (void) {
00106     return _maxAllocated;
00107   }
00108 
00109   int getInUseAtMaxAllocated (void) {
00110     return _inUseAtMaxAllocated;
00111   }
00112 
00113   int getMaxRequested (void) {
00114     return _maxRequested;
00115   }
00116   
00117 #endif
00118 
00119 private:
00120 
00121   // Hide the lock & unlock methods.
00122 
00123   inline void lock (void) {
00124     hoardHeap::lock();
00125   }
00126 
00127   inline void unlock (void) {
00128     hoardHeap::unlock();
00129   }
00130 
00131   // Prevent copying and assignment.
00132   processHeap (const processHeap&);
00133   const processHeap& operator= (const processHeap&);
00134 
00135   // The per-thread heaps.
00136   threadHeap theap[MAX_HEAPS];
00137 
00138   // The global persistent heap
00139   persistentHeap *_persistentHeap;
00140 
00141 #if HEAP_FRAG_STATS
00142   // Statistics required to compute fragmentation.  We cannot
00143   // unintrusively keep track of these on a multiprocessor, because
00144   // this would become a bottleneck.
00145 
00146   int _currentAllocated;
00147   int _currentRequested;
00148   int _maxAllocated;
00149   int _maxRequested;
00150   int _inUseAtMaxAllocated;
00151   int _fragmentation;
00152 
00153   // A lock to protect these statistics.
00154   hoardLockType _statsLock;
00155 #endif
00156 
00157 #if HEAP_LOG
00158   Log<MemoryRequest> _log[MAX_HEAPS + 1];
00159 #endif
00160 
00161   // A lock for the superblock buffer.
00162   hoardLockType _bufferLock;
00163 
00164   char *        _buffer;
00165   int           _bufferCount;
00166 };
00167 
00168 
00169 threadHeap& processHeap::getHeap (int i)
00170 {
00171   assert (i >= 0);
00172   assert (i < MAX_HEAPS);
00173   return theap[i];
00174 }
00175 
00176 
00177 #if HEAP_LOG
00178 Log<MemoryRequest>& processHeap::getLog (int i)
00179 {
00180   assert (i >= 0);
00181   assert (i < MAX_HEAPS + 1);
00182   return _log[i];
00183 }
00184 #endif
00185 
00186 
00187 // Return ceil(log_2(num)).
00188 // num must be positive.
00189 static inline int lg (int num)
00190 {
00191   assert (num > 0);
00192   int power = 0;
00193   int n = 1;
00194   // Invariant: 2^power == n.
00195   while (n < num) {
00196     n <<= 1;
00197     power++;
00198   }
00199   return power;
00200 }
00201 
00202 
00203 // Hash out the thread id to a heap and return an index to that heap.
00204 int processHeap::getHeapIndex (void) {
00205 //  int tid = hoardGetThreadID() & hoardHeap::_numProcessorsMask;
00206   int tid = hoardGetThreadID() & MAX_HEAPS_MASK;
00207   assert (tid < MAX_HEAPS);
00208   return tid;
00209 }
00210 
00211 
00212 superblock * processHeap::acquire (const int sizeclass,
00213                                    hoardHeap * dest)
00214 {
00215   lock ();
00216 
00217   // Remove the superblock with the most free space.
00218   superblock * maxSb = removeMaxSuperblock (sizeclass);
00219   if (maxSb) {
00220     maxSb->setOwner (dest);
00221   }
00222 
00223   unlock ();
00224 
00225   return maxSb;
00226 }
00227 
00228 
00229 // Put a superblock back into our list of superblocks.
00230 void processHeap::release (superblock * sb)
00231 {
00232   assert (EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
00233 
00234   lock();
00235 
00236   // Insert the superblock.
00237   insertSuperblock (sb->getBlockSizeClass(), sb, this);
00238 
00239   unlock();
00240 }
00241 
00242 
00243 #endif // _PROCESSHEAP_H_
00244 

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