|
@@ -40,7 +40,6 @@
|
|
|
#include "trace.h"
|
|
|
|
|
|
#include "default_rb.h"
|
|
|
-#include "freelist/block_header_funcs.h"
|
|
|
|
|
|
#ifdef BITMAP_RB_ONLY
|
|
|
#error Current memory-aligned allocation implementation supports only \
|
|
@@ -70,93 +69,16 @@ int posix_memalign(void **memptr, size_t alignment, size_t size) {
|
|
|
LOCK_RAW_BLOCK(raw_block);
|
|
|
encapsulated_rb = (freelist_rb_t *)
|
|
|
((uintptr_t) raw_block + sizeof(raw_block_header_t));
|
|
|
- *memptr = dmmlib_malloc(encapsulated_rb, size + alignment - 1);
|
|
|
+ *memptr = freelist_memalign(encapsulated_rb, alignment, size);
|
|
|
UNLOCK_RAW_BLOCK(raw_block);
|
|
|
-
|
|
|
-CheckAlignment:
|
|
|
-
|
|
|
- if(*memptr != NULL) {
|
|
|
-
|
|
|
- /* Check that a valid pointer has been returned */
|
|
|
- assert(((uintptr_t) raw_block < (uintptr_t) *memptr) &&
|
|
|
- ((uintptr_t) *memptr < (uintptr_t) raw_block +
|
|
|
- raw_block->size));
|
|
|
-
|
|
|
- if(((uintptr_t) *memptr) % alignment == 0) {
|
|
|
- /* Memory address is already aligned, no need for
|
|
|
- * modifications */
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- size_t padding = (- (size_t) *memptr) & (alignment - 1);
|
|
|
-
|
|
|
- block_header_t *block_header = get_header(*memptr);
|
|
|
-
|
|
|
- /* Check if the currently selected memory block is the first
|
|
|
- * allocated in the raw block. If it is, then there is no previous
|
|
|
- * block in the data layout, so we cannot increase its size as this
|
|
|
- * would conclude to wasted space. Instead of this, we try to
|
|
|
- * allocate another block which is guaranteed not to be the first
|
|
|
- * memory block at this point. If we find one, then we free the
|
|
|
- * first allocated block and repeat the process of alignment.
|
|
|
- * Otherwise, we go to the next raw block. */
|
|
|
-
|
|
|
- size_t previous_size_availability =
|
|
|
- get_previous_size_availability(block_header);
|
|
|
-
|
|
|
- if(previous_size_availability == 1) {
|
|
|
- void *old_ptr = *memptr;
|
|
|
-
|
|
|
- *memptr = dmmlib_malloc(encapsulated_rb, size + alignment - 1);
|
|
|
-
|
|
|
- dmmlib_free(encapsulated_rb, old_ptr);
|
|
|
-
|
|
|
- if(*memptr != NULL) {
|
|
|
- goto CheckAlignment;
|
|
|
- } else {
|
|
|
- /* Abandon current raw block */
|
|
|
- }
|
|
|
- } else {
|
|
|
- size_t previous_size = previous_size_availability >> 1;
|
|
|
- size_t previous_availability = previous_size_availability & 1;
|
|
|
- block_header_t *previous_block = (block_header_t *)
|
|
|
- ((uintptr_t) block_header - previous_size);
|
|
|
-
|
|
|
- block_header_t *next_block = get_dlnext(encapsulated_rb,
|
|
|
- block_header);
|
|
|
-
|
|
|
- previous_size += padding;
|
|
|
- previous_block->size = (previous_size << 1) |
|
|
|
- previous_availability;
|
|
|
-
|
|
|
- block_header->previous_size = (previous_size << 1) |
|
|
|
- previous_availability;
|
|
|
-
|
|
|
- size_t new_size = get_size(block_header) - padding;
|
|
|
-
|
|
|
- block_header->size = (new_size << 1) | 1;
|
|
|
-
|
|
|
- if(next_block != NULL) {
|
|
|
- next_block->previous_size = block_header->size;
|
|
|
- } else { /* The aligned memory block is the border pointer */
|
|
|
- encapsulated_rb->border_ptr = (block_header_t *)
|
|
|
- ((uintptr_t) block_header + padding);
|
|
|
- }
|
|
|
-
|
|
|
- memcpy((void *) ((uintptr_t) block_header + padding),
|
|
|
- (void *) block_header, HEADER_SIZE);
|
|
|
-
|
|
|
- *memptr = (void *)((uintptr_t) *memptr + padding);
|
|
|
-
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
if(*memptr == NULL) {
|
|
|
|
|
|
- if( 2 * size > SYS_ALLOC_SIZE - sizeof(raw_block_header_t) -
|
|
|
- sizeof(freelist_rb_t)) { /* A big block has to be created */
|
|
|
+ if( 2 * (size + alignment - 1) > SYS_ALLOC_SIZE -
|
|
|
+ sizeof(raw_block_header_t) - sizeof(freelist_rb_t)) {
|
|
|
+
|
|
|
+ /* A big block has to be created */
|
|
|
|
|
|
*memptr = (void *)create_raw_block(size + alignment - 1 +
|
|
|
sizeof(raw_block_header_t), BIGBLOCK);
|
|
@@ -165,9 +87,11 @@ CheckAlignment:
|
|
|
*memptr = (void *)((uintptr_t) *memptr +
|
|
|
sizeof(raw_block_header_t));
|
|
|
|
|
|
+ /* Check if alignment is needed */
|
|
|
if(((uintptr_t) *memptr) % alignment != 0) {
|
|
|
size_t padding = (- (size_t) *memptr) & (alignment - 1);
|
|
|
|
|
|
+ /* Copy the raw block's header to the new location */
|
|
|
memcpy((void *)((uintptr_t) *memptr
|
|
|
- sizeof(raw_block_header_t) + padding),
|
|
|
(void *)((uintptr_t) *memptr
|
|
@@ -175,12 +99,20 @@ CheckAlignment:
|
|
|
sizeof(raw_block_header_t)
|
|
|
);
|
|
|
|
|
|
- munmap((void *)((uintptr_t) *memptr
|
|
|
- - sizeof(raw_block_header_t)
|
|
|
- - padding),
|
|
|
- (size_t) padding);
|
|
|
-
|
|
|
+ /* Update *memptr */
|
|
|
*memptr = (void *)((uintptr_t) *memptr + padding);
|
|
|
+
|
|
|
+ /* Update big block's size and requested size */
|
|
|
+ raw_block_header_t *aligned_header =
|
|
|
+ (raw_block_header_t *)((uintptr_t) *memptr -
|
|
|
+ sizeof(raw_block_header_t));
|
|
|
+ LOCK_RAW_BLOCK(aligned_header);
|
|
|
+ aligned_header->size -= padding;
|
|
|
+#ifdef REQUEST_SIZE_INFO
|
|
|
+ aligned_header->requested_size = size;
|
|
|
+#endif /* REQUEST_SIZE_INFO */
|
|
|
+ UNLOCK_RAW_BLOCK(aligned_header);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
#ifdef WITH_DEBUG
|
|
@@ -190,7 +122,8 @@ CheckAlignment:
|
|
|
SLIST_INSERT_HEAD(&systemallocator.bb_head,
|
|
|
(raw_block_header_t *) ((uintptr_t) *memptr -
|
|
|
sizeof(raw_block_header_t)), pointers);
|
|
|
- UNLOCK_RAW_BLOCK(((raw_block_header_t *) *memptr));
|
|
|
+ UNLOCK_RAW_BLOCK(((raw_block_header_t *) ((uintptr_t) *memptr -
|
|
|
+ sizeof(raw_block_header_t))));
|
|
|
UNLOCK_GLOBAL();
|
|
|
#endif /* WITH_DEBUG */
|
|
|
|
|
@@ -206,12 +139,8 @@ CheckAlignment:
|
|
|
|
|
|
encapsulated_rb = (DEFAULT_RB_T *)
|
|
|
((uintptr_t) raw_block + sizeof(raw_block_header_t));
|
|
|
- *memptr = dmmlib_malloc(encapsulated_rb, size + alignment - 1);
|
|
|
+ *memptr = freelist_memalign(encapsulated_rb, alignment, size);
|
|
|
UNLOCK_RAW_BLOCK(raw_block);
|
|
|
-
|
|
|
- if(*memptr != NULL) {
|
|
|
- goto CheckAlignment;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|