usermode/library/malloc-original/src/persistentsuperblock.h

00001 #ifndef _PERSISTENTSUPERBLOCK_H
00002 #define _PERSISTENTSUPERBLOCK_H
00003 
00004 #include "config.h"
00005 
00006 #include <iostream>
00007 #include <stdint.h>
00008 #include <assert.h>
00009 #include <pcm.h>
00010 #include "hoardheap.h"
00011 
00012 class superblock; // forward declaration
00013 
00014 #if 0
00015 # define __BITMAP_ZERO(bitsetp) \
00016   do {                                                                        \
00017     unsigned int __i;                                                         \
00018     bitmap_t *__arr = (bitsetp);                                              \
00019     for (__i = 0; __i < sizeof (bitmap_t) / sizeof (__bitmap_mask); ++__i)      \
00020       __arr->__bits[__i] = 0;                                                 \
00021   } while (0)
00022 #endif
00023 
00024 //FIXME: PCM_NT_STORE must be replaced with transactional barrier 
00025 
00026 /* Basic access macros for bitmaps.  */
00027 # define __BITMAPELT(bit)       ((bit) / BITMAP_ARRAY_ENTRY_SIZE_BITS)
00028 # define __BITMAPMASK(bit)      ((uint64_t) 1 << ((bit) % BITMAP_ARRAY_ENTRY_SIZE_BITS))
00029 # define __BITMAP_SET(set, bit, bitmap)                               \
00030   PCM_NT_STORE(set, &bitmap[__BITMAPELT (bit)],                       \
00031                bitmap[__BITMAPELT (bit)] | __BITMAPMASK (bit));
00032 # define __BITMAP_CLR(set, bit, bitmap)                               \
00033   PCM_NT_STORE(set, &bitmap[__BITMAPELT (bit)],                       \
00034                bitmap[__BITMAPELT (bit)] & ~__BITMAPMASK (bit));
00035 # define __BITMAP_ISSET(bit, bitmap) \
00036   ((bitmap[__BITMAPELT (bit)] & __BITMAPMASK (bit)) != 0)
00037 
00038 
00039 class persistentSuperblock {
00040 
00041 public:
00042         enum { PERSISTENTSUPERBLOCK_SIZE = SUPERBLOCK_SIZE  };
00043         enum { PERSISTENTBLOCK_MIN_SIZE = 8  };
00044         enum { BITMAP_SIZE = PERSISTENTSUPERBLOCK_SIZE / PERSISTENTBLOCK_MIN_SIZE  };
00045         enum { BITMAP_ARRAY_ENTRY_SIZE_BITS = 8 * sizeof(uint64_t)  };
00046         enum { BITMAP_ARRAY_ENTRY_MASK = -1  };
00047         enum { BITMAP_ARRAY_SIZE = BITMAP_SIZE / BITMAP_ARRAY_ENTRY_SIZE_BITS  };
00048 
00049         persistentSuperblock(char *pregion) {
00050                 int            i;
00051                 pcm_storeset_t *set = pcm_storeset_get();
00052 
00053                 for (i=0; i<BITMAP_ARRAY_SIZE; i++) {
00054                         PCM_NT_STORE(set, &_bitmap[i], 0);
00055                 }
00056                 PCM_NT_STORE(set, (volatile pcm_word_t *) &_pregion, (pcm_word_t) pregion); /* _pregion is a pointer, so it has a size of 64-bit on 64-bit systems */
00057                 PCM_NT_STORE(set, (volatile pcm_word_t *) &_blksize, (pcm_word_t) PERSISTENTBLOCK_MIN_SIZE);
00058                 PCM_NT_FLUSH(set);
00059         }
00060 
00061         void volatileInit() {
00062                 _cached = false;
00063                 _acquired = false;
00064         }
00065 
00066         bool isAcquired() {
00067                 return _acquired;
00068         }
00069 
00070         void acquire() {
00071                 _acquired = true;
00072         }
00073 
00074         int getFullness() {
00075                 int i;
00076                 int setBits = 0;
00077 
00078                 for (i=0; i<BITMAP_SIZE; i++) {
00079                         if (__BITMAP_ISSET(i, _bitmap)) {
00080                                 setBits++;
00081                         }
00082                 }
00083 
00084                 return (SUPERBLOCK_FULLNESS_GROUP-1) * setBits / BITMAP_SIZE;
00085         }
00086 
00087         void allocBlock(int index) {
00088                 int            bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00089                 int            firstBit = index * bitsPerBlock;
00090                 int            i;
00091                 pcm_storeset_t *set = pcm_storeset_get();
00092 
00093                 for (i=firstBit; i<firstBit+bitsPerBlock; i++) {
00094                         __BITMAP_SET(set, i, _bitmap);
00095                 }
00096         }
00097 
00098         void freeBlock(int index) {
00099                 int            bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00100                 int            firstBit = index * bitsPerBlock;
00101                 int            i;
00102                 pcm_storeset_t *set = pcm_storeset_get();
00103 
00104                 for (i=firstBit; i<firstBit+bitsPerBlock; i++) {
00105                         __BITMAP_CLR(set, i, _bitmap);
00106                 }
00107         }
00108 
00109         bool isBlockFree(int index) {
00110                 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00111                 int firstBit = index * bitsPerBlock;
00112 
00113                 if (__BITMAP_ISSET(firstBit, _bitmap)) {
00114                         return false;
00115                 }
00116                 return true;
00117         }
00118 
00119 
00120         void * getBlockRegion(int index) {
00121                 return (void *) (_pregion + index * _blksize);
00122         }
00123         
00124         int getNumBlocks (void)
00125         {
00126                 return PERSISTENTSUPERBLOCK_SIZE/_blksize;
00127         }
00128 
00129         int getNumAvailable (void)
00130         {
00131                 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00132                 int i;
00133                 int numAvailable = 0;
00134 
00135                 for (i=0; i<BITMAP_SIZE; i+=bitsPerBlock) {
00136                         if (__BITMAP_ISSET(i, _bitmap)) {
00137                                 numAvailable++;
00138                         }
00139                 }
00140 
00141                 return PERSISTENTSUPERBLOCK_SIZE/_blksize;
00142         }
00143 
00144         bool isFree() {
00145                 int i;
00146 
00147                 for (i=0; i<BITMAP_ARRAY_SIZE; i++) {
00148                         if (_bitmap[i] != 0) {
00149                                 return false;
00150                         }
00151                 }
00152         
00153                 return true;
00154         }
00155 
00156         void setBlockSize(int blksize) {
00157                 assert(isFree() == true); // block must be free to change its size class 
00158                 _blksize = blksize;
00159         }
00160 
00161         int getBlockSize() {
00162                 return _blksize;
00163         }
00164 
00165         void makePersistentSuperblock(int blksize);
00166 
00167         superblock *getSuperblock() {
00168                 return _superblock;
00169         }
00170 
00171         void setSuperblock(superblock *sb) {
00172                 _superblock = sb;
00173         }
00174 
00175 private:
00176         uint64_t _blksize;
00177         uint64_t _bitmap[BITMAP_ARRAY_SIZE];
00178         char     *_pregion;
00179 
00180         // volatile members
00181         bool       _cached;
00182         bool       _acquired;
00183         superblock *_superblock; // points to the volatile superblock caching this persistent superblock
00184 };
00185 
00186 #endif

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