Eneboo - Documentación para desarrolladores
|
00001 // -*- C++ -*- 00002 00003 /* 00004 00005 Heap Layers: An Extensible Memory Allocation Infrastructure 00006 00007 Copyright (C) 2000-2004 by Emery Berger 00008 http://www.cs.umass.edu/~emery 00009 emery@cs.umass.edu 00010 00011 This program is free software; you can redistribute it and/or modify 00012 it under the terms of the GNU General Public License as published by 00013 the Free Software Foundation; either version 2 of the License, or 00014 (at your option) any later version. 00015 00016 This program is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 GNU General Public License for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with this program; if not, write to the Free Software 00023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00024 00025 */ 00026 00033 #ifndef _BITSTRING_H_ 00034 #define _BITSTRING_H_ 00035 00036 #include <assert.h> 00037 00038 template <int N> 00039 class BitString { 00040 public: 00041 00042 BitString (void) { 00043 clear(); 00044 } 00045 00046 inline void clear (void) { 00047 for (int i = 0; i < NUM_ULONGS; i++) { 00048 B[i] = ALL_ALLOCATED; 00049 } 00050 firstPos = 0; 00051 } 00052 00053 // Bit = 1 == allocated. 00054 int allocate (int length, int alignment) { 00055 // Start at the first entry. 00056 for (int bitPos = firstPos; bitPos < N; ) { 00057 // If the whole entry here is allocated, 00058 // skip to the next one. 00059 if (B[bitPos >> SHIFTS_PER_ULONG] == ALL_ALLOCATED) { 00060 bitPos = ((bitPos >> SHIFTS_PER_ULONG) + 1) << SHIFTS_PER_ULONG; 00061 // Adjust for alignment if needed. 00062 while ((bitPos % alignment) != 0) { 00063 bitPos++; 00064 } 00065 continue; 00066 } 00067 // If this bit is set, skip to the next one. 00068 if (get(bitPos)) { 00069 bitPos += alignment; 00070 continue; 00071 } 00072 // Got something free -- let's see if we have a run of the requisite length. 00073 bool gotOne = true; 00074 for (int j = 0; j < length; j++) { 00075 if (get(bitPos + j)) { 00076 gotOne = false; 00077 bitPos += j; 00078 // Adjust for alignment if needed. 00079 while ((bitPos % alignment) != 0) { 00080 bitPos++; 00081 } 00082 break; 00083 } 00084 } 00085 if (gotOne) { 00086 // We found one - claim it! 00087 for (int j = 0; j < length; j++) { 00088 set(bitPos + j); 00089 } 00090 return bitPos; 00091 } 00092 } 00093 // Error - none found. 00094 return -1; 00095 } 00096 00097 void free (int bitPos, int length) { 00098 for (int j = bitPos; j < bitPos + length; j++) { 00099 reset (j); 00100 } 00101 } 00102 00103 #if 0 00104 inline int first (void) const { 00105 for (int i = 0; i < NUM_ULONGS; i++) { 00106 if (B[i] > 0) { 00107 unsigned long index = 1U << (BITS_PER_ULONG-1); 00108 for (int j = 0; j < BITS_PER_ULONG; j++) { 00109 if (B[i] & index) { 00110 return j + i * BITS_PER_ULONG; 00111 } 00112 index >>= 1; 00113 } 00114 } 00115 } 00116 return -1; 00117 } 00118 #endif 00119 00120 inline int firstAfter (const int index) const { 00121 #if 0 00122 for (int i = index; i < N; i++ ) { 00123 int ind = i >> SHIFTS_PER_ULONG; 00124 if (B[ind] & (1U << (i & (BITS_PER_ULONG - 1)))) { 00125 return i; 00126 } 00127 } 00128 return -1; 00129 #else 00130 int indmask = index - (index >> SHIFTS_PER_ULONG) * BITS_PER_ULONG; 00131 for (int i = index >> SHIFTS_PER_ULONG; i < NUM_ULONGS; i++) { 00132 if (B[i]) { 00133 unsigned long bitval = B[i]; 00134 bitval &= ~((1 << (indmask & (BITS_PER_ULONG - 1))) - 1); 00135 if (bitval) { 00136 return (i * BITS_PER_ULONG + lsb(bitval)); 00137 } 00138 } 00139 indmask = indmask - BITS_PER_ULONG; 00140 if (indmask < 0) { 00141 indmask = 0; 00142 } 00143 } 00144 return -1; 00145 #endif 00146 } 00147 00148 inline bool get (const int index) const { 00149 assert (index >= 0); 00150 assert (index < N); 00151 int ind = index >> SHIFTS_PER_ULONG; 00152 assert (ind >= 0); 00153 assert (ind < NUM_ULONGS); 00154 return (B[ind] & (1U << (index & (BITS_PER_ULONG - 1)))); 00155 } 00156 00157 inline void set (const int index) { 00158 assert (index >= 0); 00159 assert (index < N); 00160 int ind = index >> SHIFTS_PER_ULONG; 00161 assert (ind >= 0); 00162 assert (ind < NUM_ULONGS); 00163 B[ind] |= (1U << (index & (BITS_PER_ULONG - 1))); 00164 if (index < firstPos) { 00165 firstPos = index; 00166 } 00167 } 00168 00169 inline void reset (const int index) { 00170 assert (index >= 0); 00171 assert (index < N); 00172 int ind = index >> SHIFTS_PER_ULONG; 00173 assert (ind >= 0); 00174 assert (ind < NUM_ULONGS); 00175 B[ind] &= ~(1U << (index & (BITS_PER_ULONG - 1))); 00176 } 00177 00178 unsigned long operator() (int index) { 00179 assert (index >= 0); 00180 assert (index < NUM_ULONGS); 00181 return B[index]; 00182 } 00183 00184 00185 private: 00186 00187 #if 1 // (sizeof(unsigned long),4) 00188 enum { BITS_PER_ULONG = 32 }; 00189 enum { SHIFTS_PER_ULONG = 5 }; 00190 #else 00191 enum { BITS_PER_ULONG = 64 }; 00192 enum { SHIFTS_PER_ULONG = 6 }; 00193 #endif 00194 00195 enum { ALL_ALLOCATED = (unsigned long) -1 }; 00196 enum { MAX_BITS = (N + BITS_PER_ULONG - 1) & ~(BITS_PER_ULONG - 1) }; 00197 enum { NUM_ULONGS = MAX_BITS / BITS_PER_ULONG }; 00198 00199 unsigned long B[NUM_ULONGS]; 00200 00202 int firstPos; 00203 00204 inline static int lsb (unsigned long b) { 00205 static const int index32[32] = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; 00206 const unsigned long debruijn32 = 0x077CB531UL; 00207 b &= (unsigned long) -((signed long) b); 00208 b *= debruijn32; 00209 b >>= 27; 00210 assert (b >= 0); 00211 assert (b < 32); 00212 return index32[b]; 00213 } 00214 00215 }; 00216 00217 00218 #endif