diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/node.c | 46 | ||||
-rw-r--r-- | src/system.c | 15 | ||||
-rw-r--r-- | src/system.h | 5 |
3 files changed, 55 insertions, 11 deletions
@@ -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); |