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 # define __BITMAPELT(bit) ((bit) / BITMAP_ARRAY_ENTRY_SIZE_BITS)
00026 # define __BITMAPMASK(bit) ((uint64_t) 1 << ((bit) % BITMAP_ARRAY_ENTRY_SIZE_BITS))
00027 # define __BITMAP_SET(set, bit, bitmap) \
00028 PCM_NT_STORE(set, &bitmap[__BITMAPELT (bit)], \
00029 bitmap[__BITMAPELT (bit)] | __BITMAPMASK (bit));
00030 # define __BITMAP_CLR(set, bit, bitmap) \
00031 PCM_NT_STORE(set, &bitmap[__BITMAPELT (bit)], \
00032 bitmap[__BITMAPELT (bit)] & ~__BITMAPMASK (bit));
00033 # define __BITMAP_ISSET(bit, bitmap) \
00034 ((bitmap[__BITMAPELT (bit)] & __BITMAPMASK (bit)) != 0)
00035
00036
00037 class persistentSuperblock {
00038
00039 public:
00040 enum { PERSISTENTSUPERBLOCK_SIZE = SUPERBLOCK_SIZE };
00041 enum { PERSISTENTBLOCK_MIN_SIZE = 8 };
00042 enum { BITMAP_SIZE = PERSISTENTSUPERBLOCK_SIZE / PERSISTENTBLOCK_MIN_SIZE };
00043 enum { BITMAP_ARRAY_ENTRY_SIZE_BITS = 8 * sizeof(uint64_t) };
00044 enum { BITMAP_ARRAY_ENTRY_MASK = -1 };
00045 enum { BITMAP_ARRAY_SIZE = BITMAP_SIZE / BITMAP_ARRAY_ENTRY_SIZE_BITS };
00046
00047 persistentSuperblock(char *pregion) {
00048 int i;
00049 pcm_storeset_t *set = pcm_storeset_get();
00050
00051 for (i=0; i<BITMAP_ARRAY_SIZE; i++) {
00052 PCM_NT_STORE(set, &_bitmap[i], 0);
00053 }
00054 PCM_NT_STORE(set, (volatile pcm_word_t *) &_pregion, (pcm_word_t) pregion);
00055 PCM_NT_STORE(set, (volatile pcm_word_t *) &_blksize, (pcm_word_t) PERSISTENTBLOCK_MIN_SIZE);
00056 PCM_NT_FLUSH(set);
00057 }
00058
00059 void volatileInit() {
00060 _cached = false;
00061 _acquired = false;
00062 }
00063
00064 bool isAcquired() {
00065 return _acquired;
00066 }
00067
00068 void acquire() {
00069 _acquired = true;
00070 }
00071
00072 int getFullness() {
00073 int i;
00074 int setBits = 0;
00075
00076 for (i=0; i<BITMAP_SIZE; i++) {
00077 if (__BITMAP_ISSET(i, _bitmap)) {
00078 setBits++;
00079 }
00080 }
00081
00082 return (SUPERBLOCK_FULLNESS_GROUP-1) * setBits / BITMAP_SIZE;
00083 }
00084
00085 void allocBlock(int index) {
00086 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00087 int firstBit = index * bitsPerBlock;
00088 int i;
00089 pcm_storeset_t *set = pcm_storeset_get();
00090
00091 for (i=firstBit; i<firstBit+bitsPerBlock; i++) {
00092 __BITMAP_SET(set, i, _bitmap);
00093 }
00094 }
00095
00096 void freeBlock(int index) {
00097 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00098 int firstBit = index * bitsPerBlock;
00099 int i;
00100 pcm_storeset_t *set = pcm_storeset_get();
00101
00102 for (i=firstBit; i<firstBit+bitsPerBlock; i++) {
00103 __BITMAP_CLR(set, i, _bitmap);
00104 }
00105 }
00106
00107 bool isBlockFree(int index) {
00108 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00109 int firstBit = index * bitsPerBlock;
00110
00111 if (__BITMAP_ISSET(firstBit, _bitmap)) {
00112 return false;
00113 }
00114 return true;
00115 }
00116
00117
00118 void * getBlockRegion(int index) {
00119 return (void *) (_pregion + index * _blksize);
00120 }
00121
00122 int getNumBlocks (void)
00123 {
00124 return PERSISTENTSUPERBLOCK_SIZE/_blksize;
00125 }
00126
00127 int getNumAvailable (void)
00128 {
00129 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00130 int i;
00131 int numAvailable = 0;
00132
00133 for (i=0; i<BITMAP_SIZE; i+=bitsPerBlock) {
00134 if (__BITMAP_ISSET(i, _bitmap)) {
00135 numAvailable++;
00136 }
00137 }
00138
00139 return PERSISTENTSUPERBLOCK_SIZE/_blksize;
00140 }
00141
00142 bool isFree() {
00143 int i;
00144
00145 for (i=0; i<BITMAP_ARRAY_SIZE; i++) {
00146 if (_bitmap[i] != 0) {
00147 return false;
00148 }
00149 }
00150
00151 return true;
00152 }
00153
00154 void setBlockSize(int blksize) {
00155 assert(isFree() == true);
00156 _blksize = blksize;
00157 }
00158
00159 int getBlockSize() {
00160 return _blksize;
00161 }
00162
00163 void makePersistentSuperblock(int blksize);
00164
00165 superblock *getSuperblock() {
00166 return _superblock;
00167 }
00168
00169 void setSuperblock(superblock *sb) {
00170 _superblock = sb;
00171 }
00172
00173 private:
00174 uint64_t _blksize;
00175 uint64_t _bitmap[BITMAP_ARRAY_SIZE];
00176 char *_pregion;
00177
00178
00179 bool _cached;
00180 bool _acquired;
00181 superblock *_superblock;
00182 };
00183
00184 #endif