|
@@ -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;
|