Phoenix
Object-oriented orthogonally persistent operating system
|
00001 /* 00002 * /phoenix/include/BitString.h 00003 * 00004 * This file is a part of Phoenix operating system. 00005 * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com> 00006 * All rights reserved. 00007 * See COPYING file for copyright details. 00008 */ 00009 00010 #ifndef BITSTRING_H_ 00011 #define BITSTRING_H_ 00012 00030 template <size_t numBits = 0> 00031 class BitString { 00032 public: 00033 inline BitString() { 00034 memset(_bits, 0, sizeof(_bits)); 00035 } 00036 00041 inline void Set(size_t idx) { 00042 ASSERT(idx < numBits); 00043 _bits[idx / NBBY] |= 1 << (idx % NBBY); 00044 } 00045 00050 inline void Clear(size_t idx) { 00051 ASSERT(idx < numBits); 00052 _bits[idx / NBBY] &= ~(1 << (idx % NBBY)); 00053 } 00054 00060 inline bool IsSet(size_t idx) { 00061 ASSERT(idx < numBits); 00062 return _bits[idx / NBBY] & (1 << (idx % NBBY)); 00063 } 00064 00070 inline bool IsClear(size_t idx) { 00071 ASSERT(idx < numBits); 00072 return !IsSet(idx); 00073 } 00074 00081 inline bool operator[](size_t idx) { 00082 return IsSet(idx); 00083 } 00084 00089 int FirstSet() { 00090 const size_t numWords = numBits / (sizeof(uintptr_t) * NBBY); 00091 for (size_t word = 0; word < numWords; word++) { 00092 uintptr_t x = static_cast<uintptr_t *>(static_cast<void *>(_bits))[word]; 00093 if (x) { 00094 size_t bit = cpu::bsf(x); 00095 bit += word * sizeof(uintptr_t) * NBBY; 00096 return bit; 00097 } 00098 } 00099 /* Check remainder. */ 00100 for (size_t idx = numWords * sizeof(uintptr_t) * NBBY; 00101 idx < numBits; 00102 idx++) { 00103 00104 if (IsSet(idx)) { 00105 return idx; 00106 } 00107 } 00108 return -1; 00109 } 00110 00115 int FirstClear() { 00116 const size_t numWords = numBits / (sizeof(uintptr_t) * NBBY); 00117 for (size_t word = 0; word < numWords; word++) { 00118 uintptr_t x = static_cast<uintptr_t *>(static_cast<void *>(_bits))[word]; 00119 if (x != static_cast<uintptr_t>(~0)) { 00120 size_t bit = cpu::bsf(~x); 00121 bit += word * sizeof(uintptr_t) * NBBY; 00122 return bit; 00123 } 00124 } 00125 /* Check remainder. */ 00126 for (size_t idx = numWords * sizeof(uintptr_t) * NBBY; 00127 idx < numBits; 00128 idx++) { 00129 00130 if (IsClear(idx)) { 00131 return idx; 00132 } 00133 } 00134 return -1; 00135 } 00136 00138 inline void ClearAll() { 00139 memset(_bits, 0, sizeof(_bits)); 00140 } 00141 00142 inline void SetAll() { 00143 memset(_bits, 0xff, sizeof(_bits)); 00144 } 00145 00146 inline void Invert() { 00147 const size_t numWords = numBits / (sizeof(uintptr_t) * NBBY); 00148 for (size_t word = 0; word < numWords; word++) { 00149 static_cast<uintptr_t *>(static_cast<void *>(_bits))[word] ^= ~0ul; 00150 } 00151 /* Invert remainder. */ 00152 for (size_t idx = numWords * sizeof(uintptr_t); 00153 idx < (numBits + NBBY - 1) / NBBY; 00154 idx++) { 00155 00156 _bits[idx] ^= 0xff; 00157 } 00158 } 00159 00160 private: 00161 u8 _bits[(numBits + NBBY - 1) / NBBY]; 00162 }; 00163 00166 template <> 00167 class BitString<0> { 00168 public: 00176 inline BitString(u8 *bitmap = 0, const size_t numBits = 0) : 00177 _bits(bitmap), 00178 _numBits(numBits), 00179 _bitmapSize((numBits + NBBY - 1) / NBBY) 00180 { 00181 if (_bits) { 00182 memset(_bits, 0, _bitmapSize); 00183 } 00184 } 00185 00190 inline void Set(size_t idx) { 00191 ASSERT(idx < _numBits); 00192 _bits[idx / NBBY] |= 1 << (idx % NBBY); 00193 } 00194 00199 inline void Clear(size_t idx) { 00200 ASSERT(idx < _numBits); 00201 _bits[idx / NBBY] &= ~(1 << (idx % NBBY)); 00202 } 00203 00209 inline bool IsSet(size_t idx) { 00210 ASSERT(idx < _numBits); 00211 return _bits[idx / NBBY] & (1 << (idx % NBBY)); 00212 } 00213 00219 inline bool IsClear(size_t idx) { 00220 ASSERT(idx < _numBits); 00221 return !IsSet(idx); 00222 } 00223 00230 inline bool operator[](size_t idx) { 00231 return IsSet(idx); 00232 } 00233 00238 int FirstSet() { 00239 const size_t numWords = _numBits / (sizeof(uintptr_t) * NBBY); 00240 for (size_t word = 0; word < numWords; word++) { 00241 uintptr_t x = static_cast<uintptr_t *>(static_cast<void *>(_bits))[word]; 00242 if (x) { 00243 size_t bit = cpu::bsf(x); 00244 bit += word * sizeof(uintptr_t) * NBBY; 00245 return bit; 00246 } 00247 } 00248 /* Check remainder. */ 00249 for (size_t idx = numWords * sizeof(uintptr_t) * NBBY; 00250 idx < _numBits; 00251 idx++) { 00252 00253 if (IsSet(idx)) { 00254 return idx; 00255 } 00256 } 00257 return -1; 00258 } 00259 00264 int FirstClear() { 00265 const size_t numWords = _numBits / (sizeof(uintptr_t) * NBBY); 00266 for (size_t word = 0; word < numWords; word++) { 00267 uintptr_t x = static_cast<uintptr_t *>(static_cast<void *>(_bits))[word]; 00268 if (x != static_cast<uintptr_t>(~0)) { 00269 size_t bit = cpu::bsf(~x); 00270 bit += word * sizeof(uintptr_t) * NBBY; 00271 return bit; 00272 } 00273 } 00274 /* Check remainder. */ 00275 for (size_t idx = numWords * sizeof(uintptr_t) * NBBY; 00276 idx < _numBits; 00277 idx++) { 00278 00279 if (IsClear(idx)) { 00280 return idx; 00281 } 00282 } 00283 return -1; 00284 } 00285 00287 inline void ClearAll() { 00288 memset(_bits, 0, _bitmapSize); 00289 } 00290 00291 inline void SetAll() { 00292 memset(_bits, 0xff, _bitmapSize); 00293 } 00294 00295 inline void Invert() { 00296 const size_t numWords = _numBits / (sizeof(uintptr_t) * NBBY); 00297 for (size_t word = 0; word < numWords; word++) { 00298 static_cast<uintptr_t *>(static_cast<void *>(_bits))[word] ^= ~0ul; 00299 } 00300 /* Invert remainder. */ 00301 for (size_t idx = numWords * sizeof(uintptr_t); 00302 idx < (_numBits + NBBY - 1) / NBBY; 00303 idx++) { 00304 00305 _bits[idx] ^= 0xff; 00306 } 00307 } 00308 private: 00309 u8 *_bits; 00310 const size_t _numBits, _bitmapSize; 00311 }; 00312 00313 #endif /* BITSTRING_H_ */