diff options
-rw-r--r-- | src/node.c | 33 | ||||
-rw-r--r-- | src/system.c | 15 | ||||
-rw-r--r-- | src/system.h | 4 |
3 files changed, 46 insertions, 6 deletions
@@ -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); |