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;
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
00025
00026
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);
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);
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
00181 bool _cached;
00182 bool _acquired;
00183 superblock *_superblock;
00184 };
00185
00186 #endif