aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2019-04-09 10:28:59 +0200
committerDavid Robillard <d@drobilla.net>2019-04-13 19:48:23 +0200
commitd4a61bf102a9d62ea2ef9ed886cae5f666ea7607 (patch)
treee1b3c8f8782372b1e135ec22f884d84491c0eb27
parenta1bd26b8ed3572e6b9e6647c092ed87b31771736 (diff)
downloadserd-d4a61bf102a9d62ea2ef9ed886cae5f666ea7607.tar.gz
serd-d4a61bf102a9d62ea2ef9ed886cae5f666ea7607.tar.bz2
serd-d4a61bf102a9d62ea2ef9ed886cae5f666ea7607.zip
Allocate nodes with posix_memalign when available
This fixes platforms where the system malloc returns memory that is not aligned to sizeof(SerdNode) (128 bits).
-rw-r--r--src/node.c15
-rw-r--r--src/system.c29
-rw-r--r--src/system.h8
3 files changed, 43 insertions, 9 deletions
diff --git a/src/node.c b/src/node.c
index 0f95d14a..2f21858e 100644
--- a/src/node.c
+++ b/src/node.c
@@ -18,6 +18,7 @@
#include "serd_internal.h"
#include "string_utils.h"
+#include "system.h"
#include "warnings.h"
#include <assert.h>
@@ -114,11 +115,13 @@ SerdNode*
serd_node_malloc(size_t n_bytes, SerdNodeFlags flags, SerdNodeType type)
{
const size_t size = sizeof(SerdNode) + serd_node_pad_size(n_bytes);
- SerdNode* node = (SerdNode*)calloc(1, size);
+ SerdNode* node = (SerdNode*)serd_calloc_aligned(size, serd_node_align);
+
+ assert((intptr_t)node % serd_node_align == 0);
+
node->n_bytes = 0;
node->flags = flags;
node->type = type;
- assert((intptr_t)node % serd_node_align == 0);
return node;
}
@@ -280,9 +283,13 @@ serd_node_copy(const SerdNode* node)
return NULL;
}
- const size_t size = serd_node_total_size(node);
serd_node_check_padding(node);
- SerdNode* copy = (SerdNode*)calloc(1, size + 3);
+
+ const size_t size = serd_node_total_size(node);
+ SerdNode* copy = (SerdNode*)serd_calloc_aligned(size + 3, serd_node_align);
+
+ assert((intptr_t)node % serd_node_align == 0);
+
memcpy(copy, node, size);
return copy;
}
diff --git a/src/system.c b/src/system.c
index 1af179f5..4d8633ee 100644
--- a/src/system.c
+++ b/src/system.c
@@ -1,5 +1,5 @@
/*
- Copyright 2011-2018 David Robillard <http://drobilla.net>
+ Copyright 2011-2019 David Robillard <http://drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -21,15 +21,36 @@
#include "serd_config.h"
#include <stdlib.h>
+#include <string.h>
void*
-serd_allocate_buffer(size_t size)
+serd_malloc_aligned(size_t size, size_t alignment)
{
#ifdef HAVE_POSIX_MEMALIGN
- void* ptr;
- const int ret = posix_memalign(&ptr, SERD_PAGE_SIZE, size);
+ void* ptr = NULL;
+ const int ret = posix_memalign(&ptr, alignment, size);
return ret ? NULL : ptr;
#else
return malloc(size);
#endif
}
+
+void*
+serd_calloc_aligned(size_t size, size_t alignment)
+{
+#ifdef HAVE_POSIX_MEMALIGN
+ void* ptr = serd_malloc_aligned(size, alignment);
+ if (ptr) {
+ memset(ptr, 0, size);
+ }
+ return ptr;
+#else
+ return calloc(1, size);
+#endif
+}
+
+void*
+serd_allocate_buffer(size_t size)
+{
+ return serd_malloc_aligned(size, SERD_PAGE_SIZE);
+}
diff --git a/src/system.h b/src/system.h
index f17eb278..dcb5dbaa 100644
--- a/src/system.h
+++ b/src/system.h
@@ -1,5 +1,5 @@
/*
- Copyright 2011-2018 David Robillard <http://drobilla.net>
+ Copyright 2011-2019 David Robillard <http://drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -38,6 +38,12 @@ serd_file_read_byte(void* buf, size_t size, size_t nmemb, void* stream)
return 1;
}
+/** Allocate a buffer aligned to `alignment` bytes. */
+void* serd_malloc_aligned(size_t size, size_t alignment);
+
+/** Allocate a zeroed buffer aligned to `alignment` bytes. */
+void* serd_calloc_aligned(size_t size, size_t alignment);
+
/** Allocate an aligned buffer for I/O. */
void* serd_allocate_buffer(size_t size);