From ff7d07e560eb32c9c10d41d25a7b8ea4cfdf7f69 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 9 Apr 2019 10:28:59 +0200 Subject: 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). --- src/node.c | 15 +++++++++++---- src/system.c | 28 +++++++++++++++++++++++++--- src/system.h | 8 +++++++- 3 files changed, 43 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/node.c b/src/node.c index 913789d7..56c8d699 100644 --- a/src/node.c +++ b/src/node.c @@ -19,6 +19,7 @@ #include "serd_internal.h" #include "static_nodes.h" #include "string_utils.h" +#include "system.h" #include #include @@ -92,11 +93,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((uintptr_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; } @@ -337,9 +340,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 8ee41640..d63b564e 100644 --- a/src/system.c +++ b/src/system.c @@ -1,5 +1,5 @@ /* - Copyright 2011-2018 David Robillard + Copyright 2011-2020 David Robillard 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,16 +21,38 @@ #include "serd_config.h" #include +#include void* -serd_allocate_buffer(size_t size) +serd_malloc_aligned(size_t size, size_t alignment) { #ifdef HAVE_POSIX_MEMALIGN void* ptr = NULL; - const int ret = posix_memalign(&ptr, SERD_PAGE_SIZE, size); + const int ret = posix_memalign(&ptr, alignment, size); return ret ? NULL : ptr; #else (void)alignment; 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 + (void)alignment; + 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..a9e6a732 100644 --- a/src/system.h +++ b/src/system.h @@ -1,5 +1,5 @@ /* - Copyright 2011-2018 David Robillard + Copyright 2011-2020 David Robillard 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); -- cgit v1.2.1