aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/node.c33
-rw-r--r--src/system.c15
-rw-r--r--src/system.h4
3 files changed, 46 insertions, 6 deletions
diff --git a/src/node.c b/src/node.c
index 21bbb4d0..ea9d174d 100644
--- a/src/node.c
+++ b/src/node.c
@@ -5,7 +5,9 @@
#include "base64.h"
#include "string_utils.h"
+#include "system.h"
+#include "serd/attributes.h"
#include "serd/buffer.h"
#include "serd/node.h"
#include "serd/string.h"
@@ -29,6 +31,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)
{
@@ -57,12 +61,26 @@ 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;
@@ -77,10 +95,13 @@ serd_node_set(SerdNode** const dst, const SerdNode* const src)
assert(dst);
assert(src);
- if (!*dst || (*dst)->length < src->length) {
- (*dst) = (SerdNode*)realloc(*dst, sizeof(SerdNode) + src->length + 1);
+ 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);
}
@@ -115,8 +136,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;
}
@@ -437,5 +458,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 072d2ed5..efd9c7ae 100644
--- a/src/system.c
+++ b/src/system.c
@@ -51,6 +51,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 081b60c4..15f93363 100644
--- a/src/system.h
+++ b/src/system.h
@@ -16,6 +16,10 @@ 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);