usermode/library/malloc-original/src/persistentheap.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   persistentheap.h
00023   ------------------------------------------------------------------------
00024   We use one persistentHeap for the whole program. It acts as a proxy to 
00025   the actual persistent superblocks stored in non-volatile memory.
00026   ------------------------------------------------------------------------
00027   Haris Volos
00028   ========================================================================
00029 */
00030 
00031 #ifndef _PERSISTENTHEAP_H_
00032 #define _PERSISTENTHEAP_H_
00033 
00034 #include "config.h"
00035 
00036 #include <stdio.h>
00037 
00038 #include "arch-specific.h"
00039 #include "hoardheap.h"
00040 #include "threadheap.h"
00041 
00042 #if HEAP_LOG
00043 #include "memstat.h"
00044 #include "log.h"
00045 #endif
00046 
00047 enum {PERSISTENTHEAP_HEADER_BASE = 0xa00000000};
00048 enum {PERSISTENTHEAP_BASE = 0xb00000000};
00049 enum {PERSISTENTSUPERBLOCK_NUM = (6*1024)};
00050 enum {PERSISTENTHEAP_SIZE = PERSISTENTSUPERBLOCK_NUM * SUPERBLOCK_SIZE};
00051 
00052 class persistentHeap : 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   persistentHeap (void);
00061 
00062   ~persistentHeap (void) {
00063 #if HEAP_STATS
00064     stats();
00065 #endif
00066   }
00067 
00068   // Format persistent heap 
00069   void format (void);
00070 
00071   // Memory deallocation routines.
00072   void free (void * ptr);
00073 
00074   // Print out statistics information.
00075   void stats (void);
00076 
00077   // Get a thread heap index.
00078   inline int getHeapIndex (void);
00079 
00080   // Get the thread heap with index i.
00081   inline threadHeap& getHeap (int i);
00082 
00083         // Extract a superblock.
00084         inline superblock * acquire (const int c,
00085                                      hoardHeap * dest);
00086 
00087   // Insert a superblock.
00088   inline void release (superblock * sb);
00089 
00090   void scavenge();
00091 
00092 #if HEAP_LOG
00093   // Get the log for index i.
00094   inline Log<MemoryRequest>& getLog (int i);
00095 #endif
00096 
00097 #if HEAP_FRAG_STATS
00098   // Declare that we have allocated an object.
00099   void setAllocated (int requestedSize,
00100                      int actualSize);
00101 
00102   // Declare that we have deallocated an object.
00103   void setDeallocated (int requestedSize,
00104                        int actualSize);
00105 
00106   // Return the number of wasted bytes at the high-water mark
00107   // (maxAllocated - maxRequested)
00108   inline int getFragmentation (void);
00109 
00110   int getMaxAllocated (void) {
00111     return _maxAllocated;
00112   }
00113 
00114   int getInUseAtMaxAllocated (void) {
00115     return _inUseAtMaxAllocated;
00116   }
00117 
00118   int getMaxRequested (void) {
00119     return _maxRequested;
00120   }
00121   
00122 #endif
00123   void *getPersistentSegmentBase()
00124   {
00125     return _psegmentBase;
00126   }
00127 
00128 private:
00129 
00130   // Hide the lock & unlock methods.
00131 
00132   inline void lock (void) {
00133     hoardHeap::lock();
00134   }
00135 
00136   inline void unlock (void) {
00137     hoardHeap::unlock();
00138   }
00139 
00140   // Prevent copying and assignment.
00141   persistentHeap (const persistentHeap&);
00142   const persistentHeap& operator= (const persistentHeap&);
00143 
00144   // The per-thread heaps.
00145   threadHeap theap[MAX_HEAPS];
00146 
00147 #if HEAP_FRAG_STATS
00148   // Statistics required to compute fragmentation.  We cannot
00149   // unintrusively keep track of these on a multiprocessor, because
00150   // this would become a bottleneck.
00151 
00152   int  _currentAllocated;
00153   int  _currentRequested;
00154   int  _maxAllocated;
00155   int  _maxRequested;
00156   int  _inUseAtMaxAllocated;
00157   int  _fragmentation;
00158 
00159   // A lock to protect these statistics.
00160   hoardLockType _statsLock;
00161 #endif
00162 
00163 #if HEAP_LOG
00164   Log<MemoryRequest> _log[MAX_HEAPS + 1];
00165 #endif
00166 
00167   // A lock for the superblock buffer.
00168   hoardLockType _bufferLock;
00169 
00170   char *        _buffer;
00171   int           _bufferCount;
00172 
00173   // The persistent segment backing the heap
00174   void *_psegmentBase;
00175 };
00176 
00177 
00178 threadHeap& persistentHeap::getHeap (int i)
00179 {
00180   assert (i >= 0);
00181   assert (i < MAX_HEAPS);
00182   return theap[i];
00183 }
00184 
00185 
00186 #if HEAP_LOG
00187 Log<MemoryRequest>& persistentHeap::getLog (int i)
00188 {
00189   assert (i >= 0);
00190   assert (i < MAX_HEAPS + 1);
00191   return _log[i];
00192 }
00193 #endif
00194 
00195 
00196 // Hash out the thread id to a heap and return an index to that heap.
00197 int persistentHeap::getHeapIndex (void) {
00198 //  int tid = hoardGetThreadID() & hoardHeap::_numProcessorsMask;
00199   int tid = hoardGetThreadID() & MAX_HEAPS_MASK;
00200   assert (tid < MAX_HEAPS);
00201   return tid;
00202 }
00203 
00204 
00205 superblock * persistentHeap::acquire (const int sizeclass,
00206                                       hoardHeap * dest)
00207 {
00208         lock ();
00209 
00210         // Remove the superblock with the most free space.
00211         superblock * maxSb = removeMaxSuperblock (sizeclass);
00212         if (maxSb) {
00213                 maxSb->setOwner (dest);
00214         }
00215 
00216         unlock ();
00217 
00218         return maxSb;
00219 }
00220 
00221 
00222 
00223 // Put a superblock back into our list of superblocks.
00224 void persistentHeap::release (superblock *sb)
00225 {
00226         assert (EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
00227 
00228         lock();
00229 
00230         // Insert the superblock.
00231         insertSuperblock (sb->getBlockSizeClass(), sb, this);
00232 
00233         unlock();
00234 }
00235 
00236 
00237 
00238 
00239 #endif // _PERSISTENTHEAP_H_
00240 

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