aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-11-12 20:18:47 +0100
committerDavid Robillard <d@drobilla.net>2020-11-13 01:15:05 +0100
commitfebc0828f271aa06681081217ee3ab2649dbf13a (patch)
treee4123cd6fdc68ba34170e897104824dabb01000c /src
parentbeed84b63136603600528c0f48bcf93f6cb51de4 (diff)
downloadserd-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.h4
-rw-r--r--src/byte_source.c5
-rw-r--r--src/system.c49
-rw-r--r--src/system.h17
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