Browse Source

Support memory requests in bitmap-organised raw blocks which require more than 2 times the bits of a bitmap vector element

Ioannis Koutras 12 years ago
parent
commit
0cd8cb2962
3 changed files with 58 additions and 65 deletions
  1. 18 17
      src/bitmap/bitmap_free.c
  2. 40 17
      src/bitmap/bitmap_malloc.c
  3. 0 31
      src/dmmlib.c

+ 18 - 17
src/bitmap/bitmap_free.c

@@ -43,8 +43,8 @@
 void bitmap_free(raw_block_header_t *raw_block, void *ptr) {
 void bitmap_free(raw_block_header_t *raw_block, void *ptr) {
     bitmap_rb_t *rb_header;
     bitmap_rb_t *rb_header;
     chunk_header_t *chunk_header;
     chunk_header_t *chunk_header;
-    size_t cells_used, cell_no, bmap_index, start_pos;
-    BMAP_EL_TYPE mask1, mask2, *bmap_p;
+    size_t cells_used, cell_no; 
+    BMAP_EL_TYPE *bmap_p;
 
 
     rb_header = (bitmap_rb_t *)((char *)raw_block + sizeof(raw_block_header_t));
     rb_header = (bitmap_rb_t *)((char *)raw_block + sizeof(raw_block_header_t));
     chunk_header = (chunk_header_t *)((char *)ptr - CHUNK_HDR_SIZE);
     chunk_header = (chunk_header_t *)((char *)ptr - CHUNK_HDR_SIZE);
@@ -99,24 +99,25 @@ void bitmap_free(raw_block_header_t *raw_block, void *ptr) {
              rb_header->elements * BMAP_EL_SIZE))
              rb_header->elements * BMAP_EL_SIZE))
         / rb_header->bytes_per_cell;
         / rb_header->bytes_per_cell;
 
 
-    bmap_index = cell_no / BMAP_EL_SIZE_BITS;
-    start_pos = cell_no % BMAP_EL_SIZE_BITS;
-
     bmap_p = (BMAP_EL_TYPE *)((char *)rb_header + sizeof(bitmap_rb_t));
     bmap_p = (BMAP_EL_TYPE *)((char *)rb_header + sizeof(bitmap_rb_t));
 
 
-    // If the sum of the starting position and the cells that are used is more
-    // than the available bits of one bitmap array element, then we have to
-    // modify the next element as well.
-    if(start_pos + cells_used <= BMAP_EL_SIZE_BITS) {
-        mask1 = make_bit_mask(start_pos + 1, cells_used);
-    } else {
-        mask1 = make_bit_mask(start_pos + 1, BMAP_EL_SIZE_BITS - start_pos);
-        mask2 = make_bit_mask((size_t) 1,
-                start_pos + cells_used - BMAP_EL_SIZE_BITS);
-
-        bmap_p[bmap_index + 1] |= mask2;
+    size_t mask_counter = cells_used;
+    size_t mask_start = cell_no % BMAP_EL_SIZE_BITS + 1;
+    unsigned int vector_index = cell_no / BMAP_EL_SIZE_BITS;
+
+    while(mask_counter != 0) {
+        if(mask_counter > BMAP_EL_SIZE_BITS) {
+            bmap_p[vector_index] |= make_bit_mask(mask_start, 
+                    BMAP_EL_SIZE_BITS - mask_start + 1);
+            mask_counter -= BMAP_EL_SIZE_BITS - mask_start + 1;
+            vector_index++;
+            mask_start = 1;
+        } else {
+            bmap_p[vector_index] |= make_bit_mask(mask_start, 
+                    mask_counter);
+            mask_counter = 0;
+        }
     }
     }
-    bmap_p[bmap_index] |= mask1;
 
 
 #ifdef HAVE_LOCKS
 #ifdef HAVE_LOCKS
     pthread_mutex_unlock(&raw_block->mutex);
     pthread_mutex_unlock(&raw_block->mutex);

+ 40 - 17
src/bitmap/bitmap_malloc.c

@@ -49,7 +49,7 @@ void * bitmap_malloc(raw_block_header_t *raw_block, size_t req_size) {
     size_t cells, stop, i, found;
     size_t cells, stop, i, found;
     void *ret;
     void *ret;
     chunk_header_t *chunk_address;
     chunk_header_t *chunk_address;
-    BMAP_EL_TYPE mask1, mask2, *bmap_p;
+    BMAP_EL_TYPE *bmap_p;
 
 
     rb_header = (bitmap_rb_t *)((char *)raw_block + sizeof(raw_block_header_t));
     rb_header = (bitmap_rb_t *)((char *)raw_block + sizeof(raw_block_header_t));
 
 
@@ -59,18 +59,19 @@ void * bitmap_malloc(raw_block_header_t *raw_block, size_t req_size) {
 
 
     req_size += CHUNK_HDR_SIZE;
     req_size += CHUNK_HDR_SIZE;
 
 
+    if(req_size >= rb_header->elements * BMAP_EL_SIZE_BITS *
+            rb_header->bytes_per_cell / 2) {
+        // Don't bother searching if you require more than half of this raw
+        // block's cells
+        return NULL;
+    }
+
     if(req_size % rb_header->bytes_per_cell > 0) {
     if(req_size % rb_header->bytes_per_cell > 0) {
         cells = req_size / rb_header->bytes_per_cell + 1;
         cells = req_size / rb_header->bytes_per_cell + 1;
     } else {
     } else {
         cells = req_size / rb_header->bytes_per_cell;
         cells = req_size / rb_header->bytes_per_cell;
     }
     }
 
 
-    // FIXME The current implementation does not allow checking cells which
-    // lie on more than two consecutive bitmap vector elements
-    if(cells > 2 * BMAP_EL_SIZE_BITS) {
-        return NULL;
-    }
-
     stop = prev_pow2(cells);
     stop = prev_pow2(cells);
 
 
 #ifdef HAVE_LOCKS
 #ifdef HAVE_LOCKS
@@ -98,35 +99,57 @@ void * bitmap_malloc(raw_block_header_t *raw_block, size_t req_size) {
     for(i = 0; i < rb_header->elements; ++i) {
     for(i = 0; i < rb_header->elements; ++i) {
         found = __builtin_ffsl(temp1[i]);
         found = __builtin_ffsl(temp1[i]);
         if(found) {
         if(found) {
-            // Check if one or two elements have to be modified
-            if(found + (cells - 1) <= BMAP_EL_SIZE_BITS) {
-                mask1 = ~make_bit_mask(found, cells);
-            } else {
-                mask1 = ~make_bit_mask(found, BMAP_EL_SIZE_BITS - found + 1);
-                mask2 = ~make_bit_mask((size_t) 1,
-                        cells - (BMAP_EL_SIZE_BITS - found) - 1);
-                bmap_p[i + 1] &= mask2;
+
+
+            // 1. Mark the occupied cells
+
+            /* Because found starts from 1, we have to add 1 to the counter. */
+            size_t mask_counter = cells;
+            size_t mask_start = found;
+            unsigned int vector_index = i;
+
+            while(mask_counter != 0) {
+                if(mask_counter > BMAP_EL_SIZE_BITS) {
+                    bmap_p[vector_index] &= ~make_bit_mask(mask_start, 
+                            BMAP_EL_SIZE_BITS - mask_start + 1);
+                    mask_counter -= BMAP_EL_SIZE_BITS - mask_start + 1;
+                    vector_index++;
+                    mask_start = 1;
+                } else {
+                    bmap_p[vector_index] &= ~make_bit_mask(mask_start, 
+                            mask_counter);
+                    mask_counter = 0;
+                }
             }
             }
-            bmap_p[i] &= mask1;
 
 
-            // Calculate the pointer to the chunk to be retrieved
+            // 2. Calculate the pointer to the chunk to be retrieved
+
             chunk_address = (chunk_header_t *)((char *)rb_header +
             chunk_address = (chunk_header_t *)((char *)rb_header +
                     sizeof(bitmap_rb_t) +
                     sizeof(bitmap_rb_t) +
                     rb_header->elements * BMAP_EL_SIZE +
                     rb_header->elements * BMAP_EL_SIZE +
                     (i * BMAP_EL_SIZE_BITS + found - 1) *
                     (i * BMAP_EL_SIZE_BITS + found - 1) *
                     rb_header->bytes_per_cell);
                     rb_header->bytes_per_cell);
+
+            // 3. Update the chunk header
+
             chunk_address->num_of_cells = cells;
             chunk_address->num_of_cells = cells;
 #ifdef REQUEST_SIZE_INFO
 #ifdef REQUEST_SIZE_INFO
             chunk_address->requested_size = req_size - CHUNK_HDR_SIZE;
             chunk_address->requested_size = req_size - CHUNK_HDR_SIZE;
 #endif /* REQUEST_SIZE_INFO */
 #endif /* REQUEST_SIZE_INFO */
 
 
+            // 4. Update the return pointer
+
             ret = (void *)((char *)chunk_address + CHUNK_HDR_SIZE);
             ret = (void *)((char *)chunk_address + CHUNK_HDR_SIZE);
 
 
+            // 5. Trace support
+
             TRACE_1("dmmlib - malloc - allocated %zu bytes"
             TRACE_1("dmmlib - malloc - allocated %zu bytes"
                     " at bitmap raw block %p\n",
                     " at bitmap raw block %p\n",
                     cells * rb_header->bytes_per_cell,
                     cells * rb_header->bytes_per_cell,
                     (void *)raw_block);
                     (void *)raw_block);
 
 
+            // 6. Statistics support
+
 #ifdef WITH_ALLOCATOR_STATS
 #ifdef WITH_ALLOCATOR_STATS
             systemallocator.dmm_stats.total_mem_allocated +=
             systemallocator.dmm_stats.total_mem_allocated +=
                 cells * rb_header->bytes_per_cell;
                 cells * rb_header->bytes_per_cell;

+ 0 - 31
src/dmmlib.c

@@ -118,37 +118,6 @@ void * malloc(size_t size) {
             systemallocator.raw_block_head = new_raw_block;
             systemallocator.raw_block_head = new_raw_block;
             pthread_mutex_unlock(&systemallocator.creation_mutex);
             pthread_mutex_unlock(&systemallocator.creation_mutex);
             ptr = dmmlib_malloc(new_raw_block, size);
             ptr = dmmlib_malloc(new_raw_block, size);
-#ifdef BITMAP_RB_ONLY
-            // FIXME If ptr is still NULL, then make a last try to allocate a
-            // big block. This has to do with the current limitation of checking
-            // max. two bitmap vector elements.
-            if(ptr == NULL) {
-                ptr = (void *) create_new_raw_block(size +
-                        sizeof(raw_block_header_t), BIGBLOCK);
-
-                if(ptr != NULL) {
-                    TRACE_1("dmmlib - malloc - allocated a whole raw block of %zu"
-                            " bytes at %p\n", size + sizeof(raw_block_header_t),
-                            (void *)ptr);
-
-#ifdef WITH_ALLOCATOR_STATS
-                    systemallocator.dmm_stats.total_mem_allocated +=
-                        size + sizeof(raw_block_header_t);
-                    systemallocator.dmm_stats.live_objects++;
-                    systemallocator.dmm_stats.num_malloc++;
-                    TRACE_1("dmmlib - global allocated memory: %zu bytes\n",
-                            systemallocator.dmm_stats.total_mem_allocated);
-#ifdef REQUEST_SIZE_INFO
-                    systemallocator.dmm_stats.total_mem_requested += size;
-                    TRACE_1("dmmlib - global requested memory: %zu bytes\n",
-                            systemallocator.dmm_stats.total_mem_requested);
-#endif /* REQUEST_SIZE_INFO */
-#endif /* WITH_ALLOCATOR_STATS */
-
-                    ptr = (void *)((char *)ptr + sizeof(raw_block_header_t));
-                }
-            }
-#endif /* BITMAP_RB_ONLY */
         }
         }
     }
     }