usermode/library/pmalloc/src/persistentheap.h

00001 /*
00002     Copyright (C) 2011 Computer Sciences Department, 
00003     University of Wisconsin -- Madison
00004 
00005     ----------------------------------------------------------------------
00006 
00007     This file is part of Mnemosyne: Lightweight Persistent Memory, 
00008     originally developed at the University of Wisconsin -- Madison.
00009 
00010     Mnemosyne was originally developed primarily by Haris Volos
00011     with contributions from Andres Jaan Tack.
00012 
00013     ----------------------------------------------------------------------
00014 
00015     Mnemosyne is free software; you can redistribute it and/or
00016     modify it under the terms of the GNU General Public License
00017     as published by the Free Software Foundation, version 2
00018     of the License.
00019  
00020     Mnemosyne is distributed in the hope that it will be useful,
00021     but WITHOUT ANY WARRANTY; without even the implied warranty of
00022     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023     GNU General Public License for more details.
00024 
00025     You should have received a copy of the GNU General Public License
00026     along with this program; if not, write to the Free Software
00027     Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00028     Boston, MA  02110-1301, USA.
00029 
00030 ### END HEADER ###
00031 */
00032 
00034 //
00035 // The Hoard Multiprocessor Memory Allocator
00036 // www.hoard.org
00037 //
00038 // Author: Emery Berger, http://www.cs.utexas.edu/users/emery
00039 //
00040 // Copyright (c) 1998-2001, The University of Texas at Austin.
00041 //
00042 // This library is free software; you can redistribute it and/or modify
00043 // it under the terms of the GNU Library General Public License as
00044 // published by the Free Software Foundation, http://www.fsf.org.
00045 //
00046 // This library is distributed in the hope that it will be useful, but
00047 // WITHOUT ANY WARRANTY; without even the implied warranty of
00048 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00049 // Library General Public License for more details.
00050 //
00052 
00061 #ifndef _PERSISTENTHEAP_H_
00062 #define _PERSISTENTHEAP_H_
00063 
00064 #include "config.h"
00065 
00066 #include <stdio.h>
00067 
00068 #include "arch-specific.h"
00069 #include "hoardheap.h"
00070 #include "threadheap.h"
00071 
00072 #if HEAP_LOG
00073 #include "memstat.h"
00074 #include "log.h"
00075 #endif
00076 
00077 //FIXME: enum types are signed types, so they can't store integer larger 
00078 // than 2G-1 thus overflowing when having a 2GBytes heap
00079 enum {PERSISTENTHEAP_HEADER_BASE = 0xa00000000};
00080 enum {PERSISTENTHEAP_BASE = 0xb00000000};
00081 enum {PERSISTENTSUPERBLOCK_NUM = (128*1024)}; /* this controls the size of the heap */
00082 #define PERSISTENTHEAP_SIZE ((uint64_t) PERSISTENTSUPERBLOCK_NUM * SUPERBLOCK_SIZE)
00083 
00084 class persistentHeap : public hoardHeap {
00085 
00086 public:
00087 
00088   // Always grab at least this many superblocks' worth of memory which
00089   // we parcel out.
00090   enum { REFILL_NUMBER_OF_SUPERBLOCKS = 16 };
00091 
00092   persistentHeap (void);
00093 
00094   ~persistentHeap (void) {
00095 #if HEAP_STATS
00096     stats();
00097 #endif
00098   }
00099 
00100   // Format persistent heap 
00101   void format (void);
00102 
00103   // Memory deallocation routines.
00104   void free (void * ptr);
00105 
00106   // Print out statistics information.
00107   void stats (void);
00108 
00109   // Get a thread heap index.
00110   inline int getHeapIndex (void);
00111 
00112   // Get the thread heap with index i.
00113   inline threadHeap& getHeap (int i);
00114 
00115         // Extract a superblock.
00116         inline superblock * acquire (const int c,
00117                                      hoardHeap * dest);
00118 
00119   // Insert a superblock.
00120   inline void release (superblock * sb);
00121 
00122   void scavenge();
00123 
00124 #if HEAP_LOG
00125   // Get the log for index i.
00126   inline Log<MemoryRequest>& getLog (int i);
00127 #endif
00128 
00129 #if HEAP_FRAG_STATS
00130   // Declare that we have allocated an object.
00131   void setAllocated (int requestedSize,
00132                      int actualSize);
00133 
00134   // Declare that we have deallocated an object.
00135   void setDeallocated (int requestedSize,
00136                        int actualSize);
00137 
00138   // Return the number of wasted bytes at the high-water mark
00139   // (maxAllocated - maxRequested)
00140   inline int getFragmentation (void);
00141 
00142   int getMaxAllocated (void) {
00143     return _maxAllocated;
00144   }
00145 
00146   int getInUseAtMaxAllocated (void) {
00147     return _inUseAtMaxAllocated;
00148   }
00149 
00150   int getMaxRequested (void) {
00151     return _maxRequested;
00152   }
00153   
00154 #endif
00155   void *getPersistentSegmentBase()
00156   {
00157     return _psegmentBase;
00158   }
00159 
00160   // Find out how large an allocated object is.
00161   static size_t objectSize (void * ptr);
00162 private:
00163 
00164   // Hide the lock & unlock methods.
00165 
00166   inline void lock (void) {
00167     hoardHeap::lock();
00168   }
00169 
00170   inline void unlock (void) {
00171     hoardHeap::unlock();
00172   }
00173 
00174   // Prevent copying and assignment.
00175   persistentHeap (const persistentHeap&);
00176   const persistentHeap& operator= (const persistentHeap&);
00177 
00178   // The per-thread heaps.
00179   threadHeap theap[MAX_HEAPS];
00180 
00181 #if HEAP_FRAG_STATS
00182   // Statistics required to compute fragmentation.  We cannot
00183   // unintrusively keep track of these on a multiprocessor, because
00184   // this would become a bottleneck.
00185 
00186   int  _currentAllocated;
00187   int  _currentRequested;
00188   int  _maxAllocated;
00189   int  _maxRequested;
00190   int  _inUseAtMaxAllocated;
00191   int  _fragmentation;
00192 
00193   // A lock to protect these statistics.
00194   hoardLockType _statsLock;
00195 #endif
00196 
00197 #if HEAP_LOG
00198   Log<MemoryRequest> _log[MAX_HEAPS + 1];
00199 #endif
00200 
00201   // A lock for the superblock buffer.
00202   hoardLockType _bufferLock;
00203 
00204   char *        _buffer;
00205   int           _bufferCount;
00206 
00207   // The persistent segment backing the heap
00208   void *_psegmentBase;
00209 };
00210 
00211 
00212 threadHeap& persistentHeap::getHeap (int i)
00213 {
00214   assert (i >= 0);
00215   assert (i < MAX_HEAPS);
00216   return theap[i];
00217 }
00218 
00219 
00220 #if HEAP_LOG
00221 Log<MemoryRequest>& persistentHeap::getLog (int i)
00222 {
00223   assert (i >= 0);
00224   assert (i < MAX_HEAPS + 1);
00225   return _log[i];
00226 }
00227 #endif
00228 
00229 
00230 // Hash out the thread id to a heap and return an index to that heap.
00231 int persistentHeap::getHeapIndex (void) {
00232 //  int tid = hoardGetThreadID() & hoardHeap::_numProcessorsMask;
00233   int tid = hoardGetThreadID() & MAX_HEAPS_MASK;
00234   assert (tid < MAX_HEAPS);
00235   return tid;
00236 }
00237 
00238 
00239 superblock * persistentHeap::acquire (const int sizeclass,
00240                                       hoardHeap * dest)
00241 {
00242         lock ();
00243 
00244         // Remove the superblock with the most free space.
00245         superblock * maxSb = removeMaxSuperblock (sizeclass);
00246         if (maxSb) {
00247                 maxSb->setOwner (dest);
00248         }
00249 
00250         unlock ();
00251 
00252         return maxSb;
00253 }
00254 
00255 
00256 
00257 // Put a superblock back into our list of superblocks.
00258 void persistentHeap::release (superblock *sb)
00259 {
00260         assert (EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
00261 
00262         lock();
00263 
00264         // Insert the superblock.
00265         insertSuperblock (sb->getBlockSizeClass(), sb, this);
00266 
00267         unlock();
00268 }
00269 
00270 
00271 
00272 
00273 #endif // _PERSISTENTHEAP_H_
00274 

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