|
|
@@ -53,17 +53,24 @@ void *memalign(size_t alignment, size_t size) {
|
|
|
void *memptr;
|
|
|
DEFAULT_RB_T *encapsulated_rb;
|
|
|
raw_block_header_t *raw_block;
|
|
|
+ size_t extra_size;
|
|
|
|
|
|
/* Verify that alignment is a power of two */
|
|
|
assert((alignment && !(alignment & (alignment - 1))) != 0);
|
|
|
|
|
|
memptr = NULL;
|
|
|
|
|
|
- /* Search the available freelist-organized raw blocks for a block whose size
|
|
|
- * is size + alignment - 1 */
|
|
|
- SLIST_FOREACH(raw_block, &systemallocator.rb_head, pointers) {
|
|
|
+ /* extra_size denotes the worst-case scenario. Because memcpy() is used, at
|
|
|
+ * least HEADER_SIZE is needed for no memory overlap. */
|
|
|
+ extra_size = sizeof(raw_block_header_t) + alignment - 1;
|
|
|
+
|
|
|
+ if(2 * (size + extra_size) < SYS_ALLOC_SIZE - sizeof(raw_block_header_t) -
|
|
|
+ sizeof(freelist_rb_t)) {
|
|
|
+
|
|
|
+ /* Search the available freelist-organized raw blocks */
|
|
|
+ SLIST_FOREACH(raw_block, &systemallocator.rb_head, pointers) {
|
|
|
#ifdef TRYLOCK_ON_MALLOC
|
|
|
- if(TRYLOCK_RAW_BLOCK(raw_block) == 0) {
|
|
|
+ if(TRYLOCK_RAW_BLOCK(raw_block) == 0) {
|
|
|
#else /* TRYLOCK_ON_MALLOC */
|
|
|
LOCK_RAW_BLOCK(raw_block);
|
|
|
#endif /* TRYLOCK_ON_MALLOC */
|
|
|
@@ -76,80 +83,11 @@ void *memalign(size_t alignment, size_t size) {
|
|
|
break;
|
|
|
}
|
|
|
#ifdef TRYLOCK_ON_MALLOC
|
|
|
- }
|
|
|
+ }
|
|
|
#endif /* TRYLOCK_ON_MALLOC */
|
|
|
- }
|
|
|
-
|
|
|
- if(memptr == NULL) {
|
|
|
-
|
|
|
- if( 2 * (size + alignment - 1) > SYS_ALLOC_SIZE -
|
|
|
- sizeof(raw_block_header_t) - sizeof(freelist_rb_t)) {
|
|
|
-
|
|
|
- /* A big block has to be created */
|
|
|
-
|
|
|
- /* extra_size denotes the worst-case scenario. Because memcpy() is
|
|
|
- * used, at least HEADER_SIZE is needed for no memory overlap. */
|
|
|
- size_t extra_size = sizeof(raw_block_header_t) + alignment - 1;
|
|
|
-
|
|
|
- memptr = (void *)create_raw_block(size + extra_size +
|
|
|
- sizeof(raw_block_header_t), BIGBLOCK);
|
|
|
-
|
|
|
- if(memptr != NULL) {
|
|
|
-
|
|
|
- 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);
|
|
|
- while(padding < sizeof(raw_block_header_t)) {
|
|
|
- padding += alignment;
|
|
|
- }
|
|
|
-
|
|
|
- /* Sometimes a deadlock is observed unless the old mutex is
|
|
|
- * destroyed.
|
|
|
- */
|
|
|
- DESTROY_RAW_BLOCK_LOCK(((raw_block_header_t *) memptr));
|
|
|
-
|
|
|
- /* 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
|
|
|
- - sizeof(raw_block_header_t)),
|
|
|
- sizeof(raw_block_header_t)
|
|
|
- );
|
|
|
-
|
|
|
- /* 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));
|
|
|
- INIT_RAW_BLOCK_LOCK(aligned_header);
|
|
|
- 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
|
|
|
- LOCK_GLOBAL();
|
|
|
- LOCK_RAW_BLOCK(((raw_block_header_t *) ((uintptr_t) memptr -
|
|
|
- sizeof(raw_block_header_t))));
|
|
|
- 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 *) ((uintptr_t) memptr -
|
|
|
- sizeof(raw_block_header_t))));
|
|
|
- UNLOCK_GLOBAL();
|
|
|
-#endif /* WITH_DEBUG */
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
- } else { /* Create a new raw block and use it */
|
|
|
+ if(memptr == NULL) { /* no block was found, try to create a new one */
|
|
|
raw_block = create_raw_block((size_t) SYS_ALLOC_SIZE,
|
|
|
DEFAULT_RB_TYPE);
|
|
|
if(raw_block != NULL) {
|
|
|
@@ -164,6 +102,62 @@ void *memalign(size_t alignment, size_t size) {
|
|
|
UNLOCK_RAW_BLOCK(raw_block);
|
|
|
}
|
|
|
}
|
|
|
+ } else { /* A big block has to be created */
|
|
|
+
|
|
|
+ memptr = (void *)create_raw_block(size + extra_size +
|
|
|
+ sizeof(raw_block_header_t), BIGBLOCK);
|
|
|
+
|
|
|
+ if(memptr != NULL) {
|
|
|
+
|
|
|
+ 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);
|
|
|
+ while(padding < sizeof(raw_block_header_t)) {
|
|
|
+ padding += alignment;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Sometimes a deadlock is observed unless the old mutex is
|
|
|
+ * destroyed. */
|
|
|
+ DESTROY_RAW_BLOCK_LOCK(((raw_block_header_t *) memptr));
|
|
|
+
|
|
|
+ /* 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 -
|
|
|
+ sizeof(raw_block_header_t)),
|
|
|
+ sizeof(raw_block_header_t)
|
|
|
+ );
|
|
|
+
|
|
|
+ /* 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));
|
|
|
+ INIT_RAW_BLOCK_LOCK(aligned_header);
|
|
|
+ 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
|
|
|
+ LOCK_GLOBAL();
|
|
|
+ LOCK_RAW_BLOCK(((raw_block_header_t *) ((uintptr_t) memptr -
|
|
|
+ sizeof(raw_block_header_t))));
|
|
|
+ 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 *) ((uintptr_t) memptr -
|
|
|
+ sizeof(raw_block_header_t))));
|
|
|
+ UNLOCK_GLOBAL();
|
|
|
+#endif /* WITH_DEBUG */
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if(memptr != NULL) {
|