usermode/library/malloc-hoard-old/src/persistentheap.cpp

00001 #include <mnemosyne.h>
00002 #include <stdint.h>
00003 #include <sys/mman.h>
00004 #include "config.h"
00005 #include "threadheap.h"
00006 #include "persistentheap.h"
00007 #include "persistentsuperblock.h"
00008 
00009 MNEMOSYNE_PERSISTENT void *psegmentheader = 0;
00010 MNEMOSYNE_PERSISTENT void *psegment = 0;
00011 
00012 persistentHeap::persistentHeap (void)
00013   : _buffer (NULL),
00014     _bufferCount (0)
00015 {
00016         int                  i;
00017         persistentSuperblock *psb;
00018 
00019         // Format persistent heap; this happens only the first time 
00020         // the heap is ever incarnated
00021         format();
00022         scavenge();
00023         
00024         // Initialize some logically non-persistent information 
00025         // FIXME: This should really be implemented as a volatile index to avoid writing PCM
00026         for(i=0; i<PERSISTENTSUPERBLOCK_NUM; i++) { 
00027                 psb = (persistentSuperblock *) ((uintptr_t) psegmentheader + i*sizeof(persistentSuperblock));
00028                 psb->volatileInit();
00029         }       
00030 }
00031 
00032 
00033 void persistentHeap::format()
00034 {
00035         int   i;
00036         void  *b;
00037         void  *buf;
00038 
00039         assert((!psegmentheader && !psegment) || (psegmentheader && psegment));
00040 
00041         if (!psegmentheader) {
00042                 psegmentheader = m_pmap((void *) PERSISTENTHEAP_HEADER_BASE, PERSISTENTSUPERBLOCK_NUM*sizeof(persistentSuperblock), PROT_READ|PROT_WRITE, 0);
00043                 psegment = m_pmap((void *)PERSISTENTHEAP_BASE, persistentSuperblock::PERSISTENTSUPERBLOCK_SIZE * PERSISTENTSUPERBLOCK_NUM, PROT_READ|PROT_WRITE, 0);
00044                 for(i=0; i<PERSISTENTSUPERBLOCK_NUM; i++) { 
00045                         b = (void *) ((uintptr_t) psegmentheader + i*sizeof(persistentSuperblock));
00046                         buf = (void *) ((uintptr_t) psegment + i*persistentSuperblock::PERSISTENTSUPERBLOCK_SIZE);
00047                         new(b) persistentSuperblock((char *)buf);
00048                 }
00049                 _psegmentBase = psegment;
00050         }
00051 }
00052 
00053 
00054 // For every persistent superblock create a superblock that higher layers can use
00055 void persistentHeap::scavenge()
00056 {
00057         int                  i;
00058         int                  sizeclass;
00059         int                  blksize;
00060         persistentSuperblock *psb;
00061         superblock           *sb;
00062 
00063         for(i=0; i<PERSISTENTSUPERBLOCK_NUM; i++) { 
00064                 psb = (persistentSuperblock *) ((uintptr_t) psegmentheader + i*sizeof(persistentSuperblock));
00065                 blksize = psb->getBlockSize();
00066                 sizeclass = sizeClass(blksize);
00067                 sb = superblock::makeSuperblock (psb);
00068                 insertSuperblock (sizeclass, sb, (persistentHeap *) NULL);
00069 #if 0
00070                 std::cout << "psb: " << psb << std::endl;
00071                 std::cout << "  ->fullness : " << psb->getFullness() << std::endl;
00072                 std::cout << "  ->isFree   : " << psb->isFree() << std::endl;
00073                 std::cout << "  ->sizeClass: " << sizeclass << std::endl;
00074                 std::cout << "  ->blksize: " << blksize << std::endl;
00075                 std::cout << "sb: " << sb << std::endl;
00076                 std::cout << "  ->numBlocks: " << sb->getNumBlocks() << std::endl;
00077                 std::cout << "  ->numAvailable: " << sb->getNumAvailable() << std::endl;
00078 #endif          
00079         }       
00080 }
00081 
00082 
00083 // Print out statistics information.
00084 void persistentHeap::stats (void) {
00085 }
00086 
00087 
00088 
00089 // free (ptr, pheap):
00090 //   inputs: a pointer to an object allocated by malloc().
00091 //   side effects: returns the block to the object's superblock;
00092 //                 updates the thread heap's statistics;
00093 //                 may release the superblock to the process heap.
00094 
00095 void persistentHeap::free (void * ptr)
00096 {
00097   // Return if ptr is 0.
00098   // This is the behavior prescribed by the standard.
00099   if (ptr == 0) {
00100     return;
00101   }
00102 
00103   // Find the block and superblock corresponding to this ptr.
00104 
00105   uintptr_t psb_index = ((uintptr_t) ptr - (uintptr_t) psegment) / persistentSuperblock::PERSISTENTSUPERBLOCK_SIZE;
00106   persistentSuperblock *psb = (persistentSuperblock *) ((uintptr_t) psegmentheader + psb_index * sizeof(persistentSuperblock));
00107   int blksize = psb->getBlockSize();
00108   uintptr_t block_index = (((uintptr_t) ptr - (uintptr_t) psegment) % persistentSuperblock::PERSISTENTSUPERBLOCK_SIZE) / blksize;
00109   superblock *sb = psb->getSuperblock();
00110   //std::cout << "block_index = " << block_index << std::endl;
00111   //std::cout << "psb = " << psb << std::endl;
00112   //std::cout << "1.sb = " << sb << std::endl;
00113   assert (sb);
00114   assert (sb->isValid());
00115   block *b = sb->getBlock(block_index);
00116   //std::cout << "2.sb = " << sb << std::endl;
00117 
00118   // Check to see if this block came from a memalign() call.
00119   // TODO: Currently we don't support memalign()
00120 
00121   b->markFree();
00122 
00123   assert (sb == b->getSuperblock());
00124   assert (sb);
00125   assert (sb->isValid());
00126 
00127   //std::cout << sb << std::endl;
00128   const int sizeclass = sb->getBlockSizeClass();
00129 
00130   //
00131   // Return the block to the superblock,
00132   // find the heap that owns this superblock
00133   // and update its statistics.
00134   //
00135 
00136   hoardHeap * owner;
00137 
00138   // By acquiring the up lock on the superblock,
00139   // we prevent it from moving to the global heap.
00140   // This eventually pins it down in one heap,
00141   // so this loop is guaranteed to terminate.
00142   // (It should generally take no more than two iterations.)
00143   sb->upLock();
00144   for (;;) {
00145     owner = sb->getOwner();
00146     owner->lock();
00147     if (owner == sb->getOwner()) {
00148       break;
00149     } else {
00150       owner->unlock();
00151     }
00152     // Suspend to allow ownership to quiesce.
00153     hoardYield();
00154   }
00155 
00156 #if HEAP_LOG
00157   MemoryRequest m;
00158   m.free (ptr);
00159   getLog (owner->getIndex()).append(m);
00160 #endif
00161 #if HEAP_FRAG_STATS
00162   setDeallocated (b->getRequestedSize(), 0);
00163 #endif
00164 
00165   std::cout << "persistentheap::free  b = " << b << " ptr = " << ptr << std::endl;
00166   int sbUnmapped = owner->freeBlock (b, sb, sizeclass, this);
00167 
00168   owner->unlock();
00169   if (!sbUnmapped) {
00170     sb->upUnlock();
00171   }
00172 }
00173 
00174 
00175 persistentSuperblock *
00176 persistentHeap::acquirePersistentSuperblock(bool isFree, int fullness, int blksize)
00177 {
00178         int i;
00179         persistentSuperblock *psb;
00180         assert(0); // deprecated interface
00181 
00182         for(i=0; i<PERSISTENTSUPERBLOCK_NUM; i++) { 
00183                 psb = (persistentSuperblock *) ((uintptr_t) psegmentheader + i*sizeof(persistentSuperblock));
00184                 //std::cout << psb << " " <<  psb->getFullness() << std::endl;
00185                 //std::cout << psb << " " <<  psb->isAcquired() << std::endl;
00186                 if (isFree == true) {
00187                         if (!psb->isAcquired() && psb->isFree() == true) {
00188                                 psb->acquire();
00189                                 psb->setBlockSize(blksize);
00190                                 return psb;
00191                         }
00192                 } else {
00193                         if (!psb->isAcquired() && psb->getFullness()==fullness 
00194                             && psb->getBlockSize() == blksize) 
00195                         {
00196                                 psb->acquire();
00197                                 return psb;
00198                         }
00199                 }
00200         }       
00201 
00202         return NULL;
00203 }

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