aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/node.c46
-rw-r--r--src/system.c15
-rw-r--r--src/system.h5
3 files changed, 55 insertions, 11 deletions
diff --git a/src/node.c b/src/node.c
index ff3f3f71..090dee99 100644
--- a/src/node.c
+++ b/src/node.c
@@ -18,9 +18,11 @@
#include "base64.h"
#include "string_utils.h"
+#include "system.h"
#include "serd/serd.h"
+#include <assert.h>
#include <float.h>
#include <math.h>
#include <stdbool.h>
@@ -38,6 +40,8 @@
# endif
#endif
+static const size_t serd_node_align = 2 * sizeof(uint64_t);
+
static size_t
serd_uri_string_length(const SerdURIView* const uri)
{
@@ -66,12 +70,27 @@ string_sink(const void* const buf, const size_t len, void* const stream)
return len;
}
+static size_t
+serd_node_pad_size(const size_t n_bytes)
+{
+ const size_t pad = sizeof(SerdNode) - (n_bytes + 2) % sizeof(SerdNode);
+ return n_bytes + 2 + pad;
+}
+
+static SERD_PURE_FUNC
+size_t
+serd_node_total_size(const SerdNode* const node)
+{
+ return node ? (sizeof(SerdNode) + serd_node_pad_size(node->length)) : 0;
+}
+
SerdNode*
serd_node_malloc(const size_t length,
const SerdNodeFlags flags,
const SerdNodeType type)
{
- SerdNode* node = (SerdNode*)calloc(1, sizeof(SerdNode) + length + 1);
+ const size_t size = sizeof(SerdNode) + serd_node_pad_size(length);
+ SerdNode* node = (SerdNode*)serd_calloc_aligned(serd_node_align, size);
node->length = 0;
node->flags = flags;
@@ -83,15 +102,20 @@ serd_node_malloc(const size_t length,
void
serd_node_set(SerdNode** const dst, const SerdNode* const src)
{
- if (src) {
- if (!(*dst) || (*dst)->length < src->length) {
- (*dst) = (SerdNode*)realloc(*dst, sizeof(SerdNode) + src->length + 1);
- }
+ if (!src) {
+ serd_free_aligned(*dst);
+ *dst = NULL;
+ return;
+ }
- memcpy(*dst, src, sizeof(SerdNode) + src->length + 1);
- } else if (*dst) {
- memset(*dst, 0, sizeof(SerdNode));
+ const size_t size = serd_node_total_size(src);
+ if (!*dst || serd_node_total_size(*dst) < size) {
+ serd_free_aligned(*dst);
+ *dst = (SerdNode*)serd_calloc_aligned(serd_node_align, size);
}
+
+ assert(*dst);
+ memcpy(*dst, src, sizeof(SerdNode) + src->length + 1);
}
SerdNode*
@@ -125,8 +149,8 @@ serd_node_copy(const SerdNode* node)
return NULL;
}
- const size_t size = sizeof(SerdNode) + node->length + 1;
- SerdNode* copy = (SerdNode*)malloc(size);
+ const size_t size = serd_node_total_size(node);
+ SerdNode* copy = (SerdNode*)serd_calloc_aligned(serd_node_align, size);
memcpy(copy, node, size);
return copy;
}
@@ -435,5 +459,5 @@ serd_node_flags(const SerdNode* const node)
void
serd_node_free(SerdNode* const node)
{
- free(node);
+ serd_free_aligned(node);
}
diff --git a/src/system.c b/src/system.c
index c3e31912..e3d8d836 100644
--- a/src/system.c
+++ b/src/system.c
@@ -64,6 +64,21 @@ serd_malloc_aligned(const size_t alignment, const size_t size)
}
void*
+serd_calloc_aligned(const size_t alignment, const size_t size)
+{
+#if defined(_WIN32) || defined(USE_POSIX_MEMALIGN)
+ void* const ptr = serd_malloc_aligned(alignment, size);
+ if (ptr) {
+ memset(ptr, 0, size);
+ }
+ return ptr;
+#else
+ (void)alignment;
+ return calloc(1, size);
+#endif
+}
+
+void*
serd_allocate_buffer(const size_t size)
{
return serd_malloc_aligned(SERD_PAGE_SIZE, size);
diff --git a/src/system.h b/src/system.h
index fdfab4a4..fae1cb84 100644
--- a/src/system.h
+++ b/src/system.h
@@ -29,6 +29,11 @@ serd_fopen(const char* path, const char* mode);
SERD_MALLOC_FUNC void*
serd_malloc_aligned(size_t alignment, size_t size);
+/// Allocate a zeroed buffer aligned to `alignment` bytes
+SERD_MALLOC_FUNC
+void*
+serd_calloc_aligned(size_t alignment, size_t size);
+
/// Allocate an aligned buffer for I/O
SERD_MALLOC_FUNC void*
serd_allocate_buffer(size_t size);