Skip to content

Commit

Permalink
Make custom malloc & realloc return aligned pointers
Browse files Browse the repository at this point in the history
Fix issue #116.

Until now, malloc_beebs and realloc_beebs returned non-aligned pointer
and this behaviour could result in a performance penalty in some tests
that use the heap, especially when executed on some architectures.

This commit makes malloc_beebs return pointers aligned to multiples of
sizeof(void *), and also updates realloc_beebs to make use of that.

To avoid breaking changes, the padding is added to heap_requested.

This commit also makes the static array used as a heap in sglib-combined
and huffbench aligned. This is obtained through the
__attribute__((aligned)) directive as it seems to be well supported
across compilers.

Reported-by: Edward Jones
Signed-off-by: Gianluca Andreotti <[email protected]>
  • Loading branch information
3rror committed Jul 5, 2021
1 parent b2cb4ba commit 11e852f
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/huffbench/libhuffbench.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
/* BEEBS heap is just an array */

#define HEAP_SIZE 8192
static char heap[HEAP_SIZE];
static char heap[HEAP_SIZE] __attribute__((aligned));

#define TEST_SIZE 500

Expand Down
2 changes: 1 addition & 1 deletion src/sglib-combined/combined.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/* BEEBS heap is just an array */

#define HEAP_SIZE 8192
static char heap[HEAP_SIZE];
static char heap[HEAP_SIZE] __attribute__((aligned));

/* General array to sort for all ops */

Expand Down
61 changes: 35 additions & 26 deletions support/beebsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,35 @@ check_heap_beebs (void *heap)
void *
malloc_beebs (size_t size)
{
void *new_ptr = heap_ptr;
if (size == 0)
return NULL;

void *next_heap_ptr = (char *)heap_ptr + size;

heap_requested += size;

if (((void *) ((char *) heap_ptr + size) > heap_end) || (0 == size))
return NULL;
else
const size_t alignment = sizeof (void *);

/* Check if the next heap pointer is aligned, otherwise add some padding */
if (((uintptr_t)next_heap_ptr % alignment) != 0)
{
heap_ptr = (void *) ((char *) heap_ptr + size);
return new_ptr;
size_t padding = alignment - ((uintptr_t)next_heap_ptr % alignment);

next_heap_ptr = (char *)next_heap_ptr + padding;

/* padding is added to heap_requested because otherwise it will break
check_heap_beebs() */
heap_requested += padding;
}

/* Check if we can "allocate" enough space */
if (next_heap_ptr > heap_end)
return NULL;

void *new_ptr = heap_ptr;
heap_ptr = next_heap_ptr;

return new_ptr;
}


Expand Down Expand Up @@ -131,31 +149,22 @@ calloc_beebs (size_t nmemb, size_t size)
void *
realloc_beebs (void *ptr, size_t size)
{
void *new_ptr = heap_ptr;

heap_requested += size;

if (((void *) ((char *) heap_ptr + size) > heap_end) || (0 == size))
if (ptr == NULL)
return NULL;
else
{
heap_ptr = (void *) ((char *) heap_ptr + size);

/* This is clunky, since we don't know the size of the original
pointer. However it is a read only action and we know it must
be big enough if we right off the end, or we couldn't have
allocated here. If the size is smaller, it doesn't matter. */
/* Get a new aligned pointer */
void *new_ptr = malloc_beebs (size);

if (NULL != ptr)
{
size_t i;
/* This is clunky, since we don't know the size of the original pointer.
However it is a read only action and we know it must be big enough if we
right off the end, or we couldn't have allocated here. If the size is
smaller, it doesn't matter. */

for (i = 0; i < size; i++)
((char *) new_ptr)[i] = ((char *) ptr)[i];
}
if (new_ptr != NULL)
for (size_t i = 0; i < size; i++)
((char *)new_ptr)[i] = ((char *)ptr)[i];

return new_ptr;
}
return new_ptr;
}


Expand Down

0 comments on commit 11e852f

Please sign in to comment.