Explorar o código

fix initial cell occupancy on a bitmap-organised raw block

Because of the raw block's size it is possible that not every bit of the last
bitmap vector element represents a memory cell. These bits have to be marked as
used during the initialization of the raw block, so that they will not be used
later on.
Ioannis Koutras %!s(int64=12) %!d(string=hai) anos
pai
achega
48400fd345
Modificáronse 1 ficheiros con 35 adicións e 3 borrados
  1. 35 3
      src/raw_block.c

+ 35 - 3
src/raw_block.c

@@ -34,6 +34,8 @@ raw_block_header_t *create_raw_block(size_t raw_block_size, rb_type type) {
 #ifdef BITMAP_RB_ONLY
     bitmap_rb_t *bitmap_rb;
     BMAP_EL_TYPE *bitmap_p;
+    size_t vector_elements;
+    size_t remaining_cells;
 #endif /* BITMAP_RB_ONLY */
 
     ptr = request_memory(raw_block_size);
@@ -60,11 +62,23 @@ raw_block_header_t *create_raw_block(size_t raw_block_size, rb_type type) {
                     sizeof(raw_block_header_t));
             bitmap_rb->bytes_per_cell = BITMAP_RESOLUTION;
 
-            bitmap_rb->elements =
-                (raw_block_size + BMAP_EL_SIZE - 
-                 sizeof(raw_block_header_t) - sizeof(bitmap_rb_t)) /
+            vector_elements =
+                (raw_block_size - sizeof(raw_block_header_t) -
+                 sizeof(bitmap_rb_t)) /
                 (BMAP_EL_SIZE + BMAP_EL_SIZE_BITS * bitmap_rb->bytes_per_cell);
 
+            remaining_cells =
+                ((raw_block_size - sizeof(raw_block_header_t) -
+                 sizeof(bitmap_rb_t)) %
+                (BMAP_EL_SIZE + BMAP_EL_SIZE_BITS * bitmap_rb->bytes_per_cell))
+                / bitmap_rb->bytes_per_cell;
+
+            if(remaining_cells == 0) {
+                bitmap_rb->elements = vector_elements;
+            } else {
+                bitmap_rb->elements = vector_elements + 1;
+            }
+
             /* Initialize the bitmap vector just right after the raw block
              * header */
             bitmap_p = (BMAP_EL_TYPE *)((char *)bitmap_rb +
@@ -73,6 +87,24 @@ raw_block_header_t *create_raw_block(size_t raw_block_size, rb_type type) {
                 *bitmap_p = BMAP_EL_INIT_VAL;
                 bitmap_p++;
             }
+
+
+            /* If there are some remaining cells, so an extra bitmap vector
+             * element is used, the cells that cannot be used by the
+             * application, have to be set as already used.
+             */
+
+            if(remaining_cells != 0) {
+
+                bitmap_p--;
+
+                for(size_t zeroes = BMAP_EL_SIZE_BITS - remaining_cells;
+                        zeroes > 0; --zeroes) {
+                    *bitmap_p <<= 1;
+                }
+
+            }
+
             break;
 #endif /* BITMAP_RB_ONLY */
         case BIGBLOCK: