00001 #include "bitmap.h"
00002 #include <debug.h>
00003 #include <limits.h>
00004 #include <round.h>
00005 #include <stdio.h>
00006 #include "threads/malloc.h"
00007 #ifdef FILESYS
00008 #include "filesys/file.h"
00009 #endif
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 typedef unsigned long elem_type;
00020
00021
00022 #define ELEM_BITS (sizeof (elem_type) * CHAR_BIT)
00023
00024
00025
00026
00027 struct bitmap
00028 {
00029 size_t bit_cnt;
00030 elem_type *bits;
00031 };
00032
00033
00034
00035 static inline size_t
00036 elem_idx (size_t bit_idx)
00037 {
00038 return bit_idx / ELEM_BITS;
00039 }
00040
00041
00042
00043 static inline elem_type
00044 bit_mask (size_t bit_idx)
00045 {
00046 return (elem_type) 1 << (bit_idx % ELEM_BITS);
00047 }
00048
00049
00050 static inline size_t
00051 elem_cnt (size_t bit_cnt)
00052 {
00053 return DIV_ROUND_UP (bit_cnt, ELEM_BITS);
00054 }
00055
00056
00057 static inline size_t
00058 byte_cnt (size_t bit_cnt)
00059 {
00060 return sizeof (elem_type) * elem_cnt (bit_cnt);
00061 }
00062
00063
00064
00065 static inline elem_type
00066 last_mask (const struct bitmap *b)
00067 {
00068 int last_bits = b->bit_cnt % ELEM_BITS;
00069 return last_bits ? ((elem_type) 1 << last_bits) - 1 : (elem_type) -1;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078 struct bitmap *
00079 bitmap_create (size_t bit_cnt)
00080 {
00081 struct bitmap *b = malloc (sizeof *b);
00082 if (b != NULL)
00083 {
00084 b->bit_cnt = bit_cnt;
00085 b->bits = malloc (byte_cnt (bit_cnt));
00086 if (b->bits != NULL || bit_cnt == 0)
00087 {
00088 bitmap_set_all (b, false);
00089 return b;
00090 }
00091 free (b);
00092 }
00093 return NULL;
00094 }
00095
00096
00097
00098
00099 struct bitmap *
00100 bitmap_create_in_buf (size_t bit_cnt, void *block, size_t block_size UNUSED)
00101 {
00102 struct bitmap *b = block;
00103
00104 ASSERT (block_size >= bitmap_buf_size (bit_cnt));
00105
00106 b->bit_cnt = bit_cnt;
00107 b->bits = (elem_type *) (b + 1);
00108 bitmap_set_all (b, false);
00109 return b;
00110 }
00111
00112
00113
00114 size_t
00115 bitmap_buf_size (size_t bit_cnt)
00116 {
00117 return sizeof (struct bitmap) + byte_cnt (bit_cnt);
00118 }
00119
00120
00121
00122
00123 void
00124 bitmap_destroy (struct bitmap *b)
00125 {
00126 if (b != NULL)
00127 {
00128 free (b->bits);
00129 free (b);
00130 }
00131 }
00132
00133
00134
00135
00136 size_t
00137 bitmap_size (const struct bitmap *b)
00138 {
00139 return b->bit_cnt;
00140 }
00141
00142
00143
00144
00145 void
00146 bitmap_set (struct bitmap *b, size_t idx, bool value)
00147 {
00148 ASSERT (b != NULL);
00149 ASSERT (idx < b->bit_cnt);
00150 if (value)
00151 bitmap_mark (b, idx);
00152 else
00153 bitmap_reset (b, idx);
00154 }
00155
00156
00157 void
00158 bitmap_mark (struct bitmap *b, size_t bit_idx)
00159 {
00160 size_t idx = elem_idx (bit_idx);
00161 elem_type mask = bit_mask (bit_idx);
00162
00163
00164
00165
00166 asm ("orl %1, %0" : "=m" (b->bits[idx]) : "r" (mask) : "cc");
00167 }
00168
00169
00170 void
00171 bitmap_reset (struct bitmap *b, size_t bit_idx)
00172 {
00173 size_t idx = elem_idx (bit_idx);
00174 elem_type mask = bit_mask (bit_idx);
00175
00176
00177
00178
00179 asm ("andl %1, %0" : "=m" (b->bits[idx]) : "r" (~mask) : "cc");
00180 }
00181
00182
00183
00184
00185 void
00186 bitmap_flip (struct bitmap *b, size_t bit_idx)
00187 {
00188 size_t idx = elem_idx (bit_idx);
00189 elem_type mask = bit_mask (bit_idx);
00190
00191
00192
00193
00194 asm ("xorl %1, %0" : "=m" (b->bits[idx]) : "r" (mask) : "cc");
00195 }
00196
00197
00198 bool
00199 bitmap_test (const struct bitmap *b, size_t idx)
00200 {
00201 ASSERT (b != NULL);
00202 ASSERT (idx < b->bit_cnt);
00203 return (b->bits[elem_idx (idx)] & bit_mask (idx)) != 0;
00204 }
00205
00206
00207
00208
00209 void
00210 bitmap_set_all (struct bitmap *b, bool value)
00211 {
00212 ASSERT (b != NULL);
00213
00214 bitmap_set_multiple (b, 0, bitmap_size (b), value);
00215 }
00216
00217
00218 void
00219 bitmap_set_multiple (struct bitmap *b, size_t start, size_t cnt, bool value)
00220 {
00221 size_t i;
00222
00223 ASSERT (b != NULL);
00224 ASSERT (start <= b->bit_cnt);
00225 ASSERT (start + cnt <= b->bit_cnt);
00226
00227 for (i = 0; i < cnt; i++)
00228 bitmap_set (b, start + i, value);
00229 }
00230
00231
00232
00233 size_t
00234 bitmap_count (const struct bitmap *b, size_t start, size_t cnt, bool value)
00235 {
00236 size_t i, value_cnt;
00237
00238 ASSERT (b != NULL);
00239 ASSERT (start <= b->bit_cnt);
00240 ASSERT (start + cnt <= b->bit_cnt);
00241
00242 value_cnt = 0;
00243 for (i = 0; i < cnt; i++)
00244 if (bitmap_test (b, start + i) == value)
00245 value_cnt++;
00246 return value_cnt;
00247 }
00248
00249
00250
00251 bool
00252 bitmap_contains (const struct bitmap *b, size_t start, size_t cnt, bool value)
00253 {
00254 size_t i;
00255
00256 ASSERT (b != NULL);
00257 ASSERT (start <= b->bit_cnt);
00258 ASSERT (start + cnt <= b->bit_cnt);
00259
00260 for (i = 0; i < cnt; i++)
00261 if (bitmap_test (b, start + i) == value)
00262 return true;
00263 return false;
00264 }
00265
00266
00267
00268 bool
00269 bitmap_any (const struct bitmap *b, size_t start, size_t cnt)
00270 {
00271 return bitmap_contains (b, start, cnt, true);
00272 }
00273
00274
00275
00276 bool
00277 bitmap_none (const struct bitmap *b, size_t start, size_t cnt)
00278 {
00279 return !bitmap_contains (b, start, cnt, true);
00280 }
00281
00282
00283
00284 bool
00285 bitmap_all (const struct bitmap *b, size_t start, size_t cnt)
00286 {
00287 return !bitmap_contains (b, start, cnt, false);
00288 }
00289
00290
00291
00292
00293
00294
00295
00296 size_t
00297 bitmap_scan (const struct bitmap *b, size_t start, size_t cnt, bool value)
00298 {
00299 ASSERT (b != NULL);
00300 ASSERT (start <= b->bit_cnt);
00301
00302 if (cnt <= b->bit_cnt)
00303 {
00304 size_t last = b->bit_cnt - cnt;
00305 size_t i;
00306 for (i = start; i <= last; i++)
00307 if (!bitmap_contains (b, i, cnt, !value))
00308 return i;
00309 }
00310 return BITMAP_ERROR;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320 size_t
00321 bitmap_scan_and_flip (struct bitmap *b, size_t start, size_t cnt, bool value)
00322 {
00323 size_t idx = bitmap_scan (b, start, cnt, value);
00324 if (idx != BITMAP_ERROR)
00325 bitmap_set_multiple (b, idx, cnt, !value);
00326 return idx;
00327 }
00328
00329
00330
00331 #ifdef FILESYS
00332
00333 size_t
00334 bitmap_file_size (const struct bitmap *b)
00335 {
00336 return byte_cnt (b->bit_cnt);
00337 }
00338
00339
00340
00341 bool
00342 bitmap_read (struct bitmap *b, struct file *file)
00343 {
00344 bool success = true;
00345 if (b->bit_cnt > 0)
00346 {
00347 off_t size = byte_cnt (b->bit_cnt);
00348 success = file_read_at (file, b->bits, size, 0) == size;
00349 b->bits[elem_cnt (b->bit_cnt) - 1] &= last_mask (b);
00350 }
00351 return success;
00352 }
00353
00354
00355
00356 bool
00357 bitmap_write (const struct bitmap *b, struct file *file)
00358 {
00359 off_t size = byte_cnt (b->bit_cnt);
00360 return file_write_at (file, b->bits, size, 0) == size;
00361 }
00362 #endif
00363
00364
00365
00366
00367 void
00368 bitmap_dump (const struct bitmap *b)
00369 {
00370 hex_dump (0, b->bits, byte_cnt (b->bit_cnt), false);
00371 }
00372