6 #include "threads/malloc.h"
8 #include "filesys/file.h"
11 /* Number of bits in an element. */
12 #define ELEM_BITS (sizeof (elem_type) * CHAR_BIT)
14 /* Returns the index of the element that contains the bit
17 elem_idx (size_t bit_idx)
19 return bit_idx / ELEM_BITS;
22 /* Returns an elem_type where only the bit corresponding to
23 BIT_IDX is turned on. */
24 static inline elem_type
25 bit_mask (size_t bit_idx)
27 return (elem_type) 1 << (bit_idx % ELEM_BITS);
30 /* Returns the number of elements required for B's bits. */
32 elem_cnt (const struct bitmap *b)
34 return DIV_ROUND_UP (b->bit_cnt, ELEM_BITS);
37 /* Returns the number of bytes required by B's elements. */
39 byte_cnt (const struct bitmap *b)
41 return sizeof (elem_type) * elem_cnt (b);
44 /* Returns a bit mask in which the bits actually used in the last
45 element of B's bits are set to 1 and the rest are set to 0. */
46 static inline elem_type
47 last_mask (const struct bitmap *b)
49 int last_bits = b->bit_cnt % ELEM_BITS;
50 return last_bits ? ((elem_type) 1 << last_bits) - 1 : (elem_type) -1;
53 /* Initializes B to be a bitmap of BIT_CNT bits.
54 Returns true if successfalse, false if memory allocation
57 bitmap_init (struct bitmap *b, size_t bit_cnt)
60 b->bits = malloc (byte_cnt (b));
61 if (b->bits == NULL && bit_cnt > 0)
64 bitmap_set_all (b, false);
68 /* Destroys bitmap B, freeing its storage. */
70 bitmap_destroy (struct bitmap *b)
77 /* Returns the number of bits in B. */
79 bitmap_size (const struct bitmap *b)
84 /* Sets the bit numbered IDX in B to VALUE. */
86 bitmap_set (struct bitmap *b, size_t idx, bool value)
89 ASSERT (idx < b->bit_cnt);
91 b->bits[elem_idx (idx)] |= bit_mask (idx);
93 b->bits[elem_idx (idx)] &= ~bit_mask (idx);
96 /* Sets all bits in B to VALUE. */
98 bitmap_set_all (struct bitmap *b, bool value)
106 for (i = 0; i < elem_cnt (b); i++)
107 b->bits[i] = value ? (elem_type) -1 : 0;
108 b->bits[elem_cnt (b) - 1] &= last_mask (b);
112 /* Sets the bit numbered IDX in B to true. */
114 bitmap_mark (struct bitmap *b, size_t idx)
116 bitmap_set (b, idx, true);
119 /* Sets the bit numbered IDX in B to false. */
121 bitmap_reset (struct bitmap *b, size_t idx)
123 bitmap_set (b, idx, false);
126 /* Toggles the bit numbered IDX in B;
127 that is, if it is true, makes it false,
128 and if it is false, makes it true. */
130 bitmap_flip (struct bitmap *b, size_t idx)
133 ASSERT (idx < b->bit_cnt);
134 b->bits[elem_idx (idx)] ^= bit_mask (idx);
137 /* Returns the value of the bit numbered IDX in B. */
139 bitmap_test (const struct bitmap *b, size_t idx)
142 ASSERT (idx < b->bit_cnt);
143 return (b->bits[elem_idx (idx)] & bit_mask (idx)) != 0;
146 /* Returns the smallest index of a bit set to VALUE in B.
147 If no bits in B are set to VALUE, returns BITMAP_ERROR. */
149 bitmap_scan (const struct bitmap *b, bool value)
151 elem_type ignore = value ? 0 : (elem_type) -1;
155 for (idx = 0; idx < elem_cnt (b); idx++)
157 elem_type e = b->bits[idx];
162 while ((e & 1) != value)
168 return idx < b->bit_cnt ? idx : BITMAP_ERROR;
174 /* Finds the smallest index of a bit set to false in B,
175 sets it to true, and returns the index.
176 If no bits in B are set to false, changes no bits and
177 returns BITMAP_ERROR. */
179 bitmap_find_and_set (struct bitmap *b)
181 size_t idx = bitmap_scan (b, false);
182 if (idx != BITMAP_ERROR)
183 bitmap_mark (b, idx);
187 /* Finds the smallest index of a bit set to true in B,
188 sets it to false, and returns the index.
189 If no bits in B are set to true, changes no bits and
190 returns BITMAP_ERROR. */
192 bitmap_find_and_clear (struct bitmap *b)
194 size_t idx = bitmap_scan (b, true);
195 if (idx != BITMAP_ERROR)
196 bitmap_reset (b, idx);
200 /* Returns the number of bits in B set to true. */
202 bitmap_set_cnt (const struct bitmap *b)
209 for (i = 0; i < elem_cnt (b); i++)
211 elem_type e = b->bits[i];
221 /* Returns true if any bits in B are set to true,
222 and false otherwise.*/
224 bitmap_any (const struct bitmap *b)
229 for (i = 0; i < elem_cnt (b); i++)
235 /* Returns the number of bits in B set to false. */
237 bitmap_clear_cnt (const struct bitmap *b)
239 return b->bit_cnt - bitmap_set_cnt (b);
242 /* Returns true if no bits in B are set to true,
243 and false otherwise.*/
245 bitmap_none (const struct bitmap *b)
247 return !bitmap_any (b);
250 /* Returns true if every bit in B is set to true,
251 and false otherwise. */
253 bitmap_all (const struct bitmap *b)
262 for (i = 0; i < elem_cnt (b) - 1; i++)
263 if (b->bits[i] != (elem_type) -1)
265 return b->bits[i] == last_mask (b);
269 /* Returns the number of bytes needed to store B in a file. */
271 bitmap_file_size (const struct bitmap *b)
276 /* Reads FILE into B, ignoring errors. */
278 bitmap_read (struct bitmap *b, struct file *file)
282 file_read_at (file, b->bits, byte_cnt (b), 0);
283 b->bits[elem_cnt (b) - 1] &= last_mask (b);
287 /* Writes FILE to B, ignoring errors. */
289 bitmap_write (const struct bitmap *b, struct file *file)
291 file_write_at (file, b->bits, byte_cnt (b), 0);
295 /* Dumps the contents of B to the console as hexadecimal. */
297 bitmap_dump (const struct bitmap *b)
299 hex_dump (b->bits, byte_cnt (b), false);