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
00020
00021 format();
00022 scavenge();
00023
00024
00025
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
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
00084 void persistentHeap::stats (void) {
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 void persistentHeap::free (void * ptr)
00096 {
00097
00098
00099 if (ptr == 0) {
00100 return;
00101 }
00102
00103
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
00111
00112
00113 assert (sb);
00114 assert (sb->isValid());
00115 block *b = sb->getBlock(block_index);
00116
00117
00118
00119
00120
00121 b->markFree();
00122
00123 assert (sb == b->getSuperblock());
00124 assert (sb);
00125 assert (sb->isValid());
00126
00127
00128 const int sizeclass = sb->getBlockSizeClass();
00129
00130
00131
00132
00133
00134
00135
00136 hoardHeap * owner;
00137
00138
00139
00140
00141
00142
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
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);
00181
00182 for(i=0; i<PERSISTENTSUPERBLOCK_NUM; i++) {
00183 psb = (persistentSuperblock *) ((uintptr_t) psegmentheader + i*sizeof(persistentSuperblock));
00184
00185
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 }