usermode/library/malloc-hoard-old/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 = 2};
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   persistentSuperblock *acquirePersistentSuperblock(bool isFree, int fullness, int sizeClass);
00092 
00093 #if HEAP_LOG
00094   // Get the log for index i.
00095   inline Log<MemoryRequest>& getLog (int i);
00096 #endif
00097 
00098 #if HEAP_FRAG_STATS
00099   // Declare that we have allocated an object.
00100   void setAllocated (int requestedSize,
00101                      int actualSize);
00102 
00103   // Declare that we have deallocated an object.
00104   void setDeallocated (int requestedSize,
00105                        int actualSize);
00106 
00107   // Return the number of wasted bytes at the high-water mark
00108   // (maxAllocated - maxRequested)
00109   inline int getFragmentation (void);
00110 
00111   int getMaxAllocated (void) {
00112     return _maxAllocated;
00113   }
00114 
00115   int getInUseAtMaxAllocated (void) {
00116     return _inUseAtMaxAllocated;
00117   }
00118 
00119   int getMaxRequested (void) {
00120     return _maxRequested;
00121   }
00122   
00123 #endif
00124   void *persistentHeap::getPersistentSegmentBase()
00125   {
00126     return _psegmentBase;
00127   }
00128 
00129 private:
00130 
00131   // Hide the lock & unlock methods.
00132 
00133   inline void lock (void) {
00134     hoardHeap::lock();
00135   }
00136 
00137   inline void unlock (void) {
00138     hoardHeap::unlock();
00139   }
00140 
00141   // Prevent copying and assignment.
00142   persistentHeap (const persistentHeap&);
00143   const persistentHeap& operator= (const persistentHeap&);
00144 
00145   // The per-thread heaps.
00146   threadHeap theap[MAX_HEAPS];
00147 
00148 #if HEAP_FRAG_STATS
00149   // Statistics required to compute fragmentation.  We cannot
00150   // unintrusively keep track of these on a multiprocessor, because
00151   // this would become a bottleneck.
00152 
00153   int  _currentAllocated;
00154   int  _currentRequested;
00155   int  _maxAllocated;
00156   int  _maxRequested;
00157   int  _inUseAtMaxAllocated;
00158   int  _fragmentation;
00159 
00160   // A lock to protect these statistics.
00161   hoardLockType _statsLock;
00162 #endif
00163 
00164 #if HEAP_LOG
00165   Log<MemoryRequest> _log[MAX_HEAPS + 1];
00166 #endif
00167 
00168   // A lock for the superblock buffer.
00169   hoardLockType _bufferLock;
00170 
00171   char *        _buffer;
00172   int           _bufferCount;
00173 
00174   // The persistent segment backing the heap
00175   void *_psegmentBase;
00176 };
00177 
00178 
00179 threadHeap& persistentHeap::getHeap (int i)
00180 {
00181   assert (i >= 0);
00182   assert (i < MAX_HEAPS);
00183   return theap[i];
00184 }
00185 
00186 
00187 #if HEAP_LOG
00188 Log<MemoryRequest>& persistentHeap::getLog (int i)
00189 {
00190   assert (i >= 0);
00191   assert (i < MAX_HEAPS + 1);
00192   return _log[i];
00193 }
00194 #endif
00195 
00196 
00197 // Hash out the thread id to a heap and return an index to that heap.
00198 int persistentHeap::getHeapIndex (void) {
00199 //  int tid = hoardGetThreadID() & hoardHeap::_numProcessorsMask;
00200   int tid = hoardGetThreadID() & MAX_HEAPS_MASK;
00201   assert (tid < MAX_HEAPS);
00202   return tid;
00203 }
00204 
00205 
00206 superblock * persistentHeap::acquire (const int sizeclass,
00207                                    hoardHeap * dest)
00208 {
00209   lock ();
00210 
00211   // Remove the superblock with the most free space.
00212   superblock * maxSb = removeMaxSuperblock (sizeclass);
00213   if (maxSb) {
00214     maxSb->setOwner (dest);
00215   }
00216 
00217   unlock ();
00218 
00219   return maxSb;
00220 }
00221 
00222 
00223 
00224 // Put a superblock back into our list of superblocks.
00225 void persistentHeap::release (superblock *)
00226 {
00227 //FIXME
00228 #if 0
00229   assert (EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
00230 
00231   lock();
00232 
00233   // Insert the superblock.
00234   insertSuperblock (sb->getBlockSizeClass(), sb, this);
00235 
00236   unlock();
00237 #endif
00238 }
00239 
00240 
00241 
00242 
00243 #endif // _PERSISTENTHEAP_H_
00244 

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