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 std::cout << " ->getFullness: " << sb->getFullness() << std::endl;
00079 #endif
00080 }
00081 }
00082
00083
00084
00085 void persistentHeap::stats (void) {
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 void persistentHeap::free (void * ptr)
00097 {
00098
00099
00100 if (ptr == 0) {
00101 return;
00102 }
00103
00104
00105
00106 uintptr_t psb_index = ((uintptr_t) ptr - (uintptr_t) psegment) / persistentSuperblock::PERSISTENTSUPERBLOCK_SIZE;
00107 persistentSuperblock *psb = (persistentSuperblock *) ((uintptr_t) psegmentheader + psb_index * sizeof(persistentSuperblock));
00108 int blksize = psb->getBlockSize();
00109 uintptr_t block_index = (((uintptr_t) ptr - (uintptr_t) psegment) % persistentSuperblock::PERSISTENTSUPERBLOCK_SIZE) / blksize;
00110 superblock *sb = psb->getSuperblock();
00111 assert (sb);
00112 assert (sb->isValid());
00113 block *b = sb->getBlock(block_index);
00114
00115
00116
00117
00118
00119
00120
00121 b->markFree();
00122
00123 assert (sb == b->getSuperblock());
00124 assert (sb);
00125 assert (sb->isValid());
00126
00127 const int sizeclass = sb->getBlockSizeClass();
00128
00129
00130
00131
00132
00133
00134
00135 hoardHeap * owner;
00136
00137
00138
00139
00140
00141
00142 sb->upLock();
00143 for (;;) {
00144 owner = sb->getOwner();
00145 owner->lock();
00146 if (owner == sb->getOwner()) {
00147 break;
00148 } else {
00149 owner->unlock();
00150 }
00151
00152 hoardYield();
00153 }
00154
00155 #if HEAP_LOG
00156 MemoryRequest m;
00157 m.free (ptr);
00158 getLog (owner->getIndex()).append(m);
00159 #endif
00160 #if HEAP_FRAG_STATS
00161 setDeallocated (b->getRequestedSize(), 0);
00162 #endif
00163
00164 int sbUnmapped = owner->freeBlock (b, sb, sizeclass, this);
00165
00166 owner->unlock();
00167 if (!sbUnmapped) {
00168 sb->upUnlock();
00169 }
00170 }