diff options
author | David Robillard <d@drobilla.net> | 2020-11-12 20:18:47 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-11-13 01:15:05 +0100 |
commit | febc0828f271aa06681081217ee3ab2649dbf13a (patch) | |
tree | e4123cd6fdc68ba34170e897104824dabb01000c /src | |
parent | beed84b63136603600528c0f48bcf93f6cb51de4 (diff) | |
download | serd-febc0828f271aa06681081217ee3ab2649dbf13a.tar.gz serd-febc0828f271aa06681081217ee3ab2649dbf13a.tar.bz2 serd-febc0828f271aa06681081217ee3ab2649dbf13a.zip |
Use aligned allocation via C11 or Windows API where possible
Diffstat (limited to 'src')
-rw-r--r-- | src/byte_sink.h | 4 | ||||
-rw-r--r-- | src/byte_source.c | 5 | ||||
-rw-r--r-- | src/system.c | 49 | ||||
-rw-r--r-- | src/system.h | 17 |
4 files changed, 63 insertions, 12 deletions
diff --git a/src/byte_sink.h b/src/byte_sink.h index f39bc2ba..876add2b 100644 --- a/src/byte_sink.h +++ b/src/byte_sink.h @@ -42,7 +42,7 @@ serd_byte_sink_new(SerdSink sink, void* stream, size_t block_size) bsink.size = 0; bsink.block_size = block_size; bsink.buf = ((block_size > 1) - ? (uint8_t*)serd_bufalloc(block_size) + ? (uint8_t*)serd_allocate_buffer(block_size) : NULL); return bsink; } @@ -60,7 +60,7 @@ static inline void serd_byte_sink_free(SerdByteSink* bsink) { serd_byte_sink_flush(bsink); - free(bsink->buf); + serd_free_aligned(bsink->buf); bsink->buf = NULL; } diff --git a/src/byte_source.c b/src/byte_source.c index d783959c..5c0404a7 100644 --- a/src/byte_source.c +++ b/src/byte_source.c @@ -22,7 +22,6 @@ #include <stdbool.h> #include <stdint.h> -#include <stdlib.h> #include <string.h> SerdStatus @@ -63,7 +62,7 @@ serd_byte_source_open_source(SerdByteSource* source, source->read_func = read_func; if (page_size > 1) { - source->file_buf = (uint8_t*)serd_bufalloc(page_size); + source->file_buf = (uint8_t*)serd_allocate_buffer(page_size); source->read_buf = source->file_buf; memset(source->file_buf, '\0', page_size); } else { @@ -102,7 +101,7 @@ SerdStatus serd_byte_source_close(SerdByteSource* source) { if (source->page_size > 1) { - free(source->file_buf); + serd_free_aligned(source->file_buf); } memset(source, '\0', sizeof(*source)); return SERD_SUCCESS; diff --git a/src/system.c b/src/system.c index 0a6a5561..fbff8806 100644 --- a/src/system.c +++ b/src/system.c @@ -25,11 +25,19 @@ # include <fcntl.h> #endif +#ifdef _WIN32 +# include <malloc.h> +#endif + #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#define SERD_HAVE_ALIGNED_ALLOCATION \ + defined(_WIN32) || defined(HAVE_ALIGNED_ALLOC) || \ + defined(HAVE_POSIX_MEMALIGN) + FILE* serd_fopen(const char* path, const char* mode) { @@ -46,14 +54,49 @@ serd_fopen(const char* path, const char* mode) } void* -serd_bufalloc(size_t size) +serd_malloc_aligned(const size_t alignment, const size_t size) { -#ifdef HAVE_POSIX_MEMALIGN +#if defined(_WIN32) + return _aligned_malloc(size, alignment); +#elif defined(HAVE_ALIGNED_ALLOC) + return aligned_alloc(alignment, size); +#elif defined(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(const size_t alignment, const size_t size) +{ +#ifdef SERD_HAVE_ALIGNED_ALLOCATION + 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); +} + +void +serd_free_aligned(void* const ptr) +{ +#ifdef _WIN32 + _aligned_free(ptr); +#else + free(ptr); +#endif +} diff --git a/src/system.h b/src/system.h index 0f6a0e0b..60095a5b 100644 --- a/src/system.h +++ b/src/system.h @@ -21,10 +21,19 @@ #include <stdio.h> -FILE* -serd_fopen(const char* path, const char* mode); +/// Open a file configured for fast sequential reading +FILE* serd_fopen(const char* path, const char* mode); -SERD_MALLOC_FUNC void* -serd_bufalloc(size_t size); +/// Allocate a buffer aligned to `alignment` bytes +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); + +/// Free a buffer allocated with an aligned allocation function +void serd_free_aligned(void* ptr); #endif // SERD_SYSTEM_H |