00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _PERSISTENTSUPERBLOCK_H
00034 #define _PERSISTENTSUPERBLOCK_H
00035
00036 #include "config.h"
00037
00038 #include <iostream>
00039 #include <stdint.h>
00040 #include <assert.h>
00041 #include <pcm.h>
00042 #include "hoardheap.h"
00043
00044 class superblock;
00045
00046 #if 0
00047 # define __BITMAP_ZERO(bitsetp) \
00048 do { \
00049 unsigned int __i; \
00050 bitmap_t *__arr = (bitsetp); \
00051 for (__i = 0; __i < sizeof (bitmap_t) / sizeof (__bitmap_mask); ++__i) \
00052 __arr->__bits[__i] = 0; \
00053 } while (0)
00054 #endif
00055
00056
00057
00058 # define __BITMAPELT(bit) ((bit) / BITMAP_ARRAY_ENTRY_SIZE_BITS)
00059 # define __BITMAPMASK(bit) ((uint64_t) 1 << ((bit) % BITMAP_ARRAY_ENTRY_SIZE_BITS))
00060 # define __BITMAP_SET(set, bit, bitmap) \
00061 PCM_NT_STORE(set, &bitmap[__BITMAPELT (bit)], \
00062 bitmap[__BITMAPELT (bit)] | __BITMAPMASK (bit));
00063 # define __BITMAP_CLR(set, bit, bitmap) \
00064 PCM_NT_STORE(set, &bitmap[__BITMAPELT (bit)], \
00065 bitmap[__BITMAPELT (bit)] & ~__BITMAPMASK (bit));
00066 # define __BITMAP_ISSET(bit, bitmap) \
00067 ((bitmap[__BITMAPELT (bit)] & __BITMAPMASK (bit)) != 0)
00068
00069
00070
00071 # define __BITMAP_CLR2(bit, bitmap) \
00072 bitmap[__BITMAPELT (bit)] = bitmap[__BITMAPELT (bit)] & ~__BITMAPMASK (bit);
00073 # define __BITMAP_SET2(bit, bitmap) \
00074 bitmap[__BITMAPELT (bit)] = bitmap[__BITMAPELT (bit)] | __BITMAPMASK (bit);
00075
00076 class persistentSuperblock {
00077
00078 public:
00079 enum { PERSISTENTSUPERBLOCK_SIZE = SUPERBLOCK_SIZE };
00080 enum { PERSISTENTBLOCK_MIN_SIZE = 8 };
00081 enum { PERSISTENTBLOCK_MAX_SIZE = 8192 };
00082 enum { BITMAP_SIZE = PERSISTENTSUPERBLOCK_SIZE / PERSISTENTBLOCK_MIN_SIZE };
00083 enum { BITMAP_ARRAY_ENTRY_SIZE_BITS = 8 * sizeof(uint64_t) };
00084 enum { BITMAP_ARRAY_ENTRY_MASK = -1 };
00085 enum { BITMAP_ARRAY_SIZE = BITMAP_SIZE / BITMAP_ARRAY_ENTRY_SIZE_BITS };
00086
00087 persistentSuperblock(char *pregion) {
00088 int i;
00089 pcm_storeset_t *set = pcm_storeset_get();
00090
00091 for (i=0; i<BITMAP_ARRAY_SIZE; i++) {
00092 PCM_NT_STORE(set, &_bitmap[i], 0);
00093 }
00094 PCM_NT_STORE(set, (volatile pcm_word_t *) &_pregion, (pcm_word_t) pregion);
00095
00096
00097
00098
00099
00100
00101
00102
00103 PCM_NT_STORE(set, (volatile pcm_word_t *) &_blksize, (pcm_word_t) PERSISTENTBLOCK_MAX_SIZE);
00104 PCM_NT_FLUSH(set);
00105 }
00106
00107 void volatileInit() {
00108 _cached = false;
00109 _acquired = false;
00110 }
00111
00112 bool isAcquired() {
00113 return _acquired;
00114 }
00115
00116 void acquire() {
00117 _acquired = true;
00118 }
00119
00120 int getFullness() {
00121 int i;
00122 int setBits = 0;
00123
00124 for (i=0; i<BITMAP_SIZE; i++) {
00125 if (__BITMAP_ISSET(i, _bitmap)) {
00126 setBits++;
00127 }
00128 }
00129
00130 return (SUPERBLOCK_FULLNESS_GROUP-1) * setBits / BITMAP_SIZE;
00131 }
00132
00133 void allocBlock(int index) {
00134 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00135 int firstBit = index * bitsPerBlock;
00136 int i;
00137
00138
00139 for (i=firstBit; i<firstBit+bitsPerBlock; i++) {
00140
00141 __BITMAP_SET2(i, _bitmap);
00142 }
00143 }
00144
00145 void freeBlock(int index) {
00146 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00147 int firstBit = index * bitsPerBlock;
00148 int i;
00149
00150
00151 for (i=firstBit; i<firstBit+bitsPerBlock; i++) {
00152
00153 __BITMAP_CLR2(i, _bitmap);
00154 }
00155 }
00156
00157 bool isBlockFree(int index) {
00158 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00159 int firstBit = index * bitsPerBlock;
00160
00161 if (__BITMAP_ISSET(firstBit, _bitmap)) {
00162 return false;
00163 }
00164 return true;
00165 }
00166
00167
00168 void * getBlockRegion(int index) {
00169 return (void *) (_pregion + index * _blksize);
00170 }
00171
00172 int getNumBlocks (void)
00173 {
00174 return PERSISTENTSUPERBLOCK_SIZE/_blksize;
00175 }
00176
00177 int getNumAvailable (void)
00178 {
00179 int bitsPerBlock = _blksize / PERSISTENTBLOCK_MIN_SIZE;
00180 int i;
00181 int numAvailable = 0;
00182
00183 for (i=0; i<BITMAP_SIZE; i+=bitsPerBlock) {
00184 if (__BITMAP_ISSET(i, _bitmap)) {
00185 numAvailable++;
00186 }
00187 }
00188
00189 return PERSISTENTSUPERBLOCK_SIZE/_blksize;
00190 }
00191
00192 bool isFree() {
00193 int i;
00194
00195 for (i=0; i<BITMAP_ARRAY_SIZE; i++) {
00196 if (_bitmap[i] != 0) {
00197 return false;
00198 }
00199 }
00200
00201 return true;
00202 }
00203
00204 void setBlockSize(int blksize) {
00205 assert(isFree() == true);
00206 _blksize = blksize;
00207 }
00208
00209 int getBlockSize() {
00210 return _blksize;
00211 }
00212
00213 void makePersistentSuperblock(int blksize);
00214
00215 superblock *getSuperblock() {
00216 return _superblock;
00217 }
00218
00219 void setSuperblock(superblock *sb) {
00220 _superblock = sb;
00221 }
00222
00223 private:
00224 uint64_t _blksize;
00225 uint64_t _bitmap[BITMAP_ARRAY_SIZE];
00226 char *_pregion;
00227
00228
00229 bool _cached;
00230 bool _acquired;
00231 superblock *_superblock;
00232 };
00233
00234 #endif