18#ifndef DT_SYSTEM_MEM_ALLOC_H
19#define DT_SYSTEM_MEM_ALLOC_H
51#define DT_IS_ALIGNED(x) __builtin_assume_aligned(x, DT_CACHELINE_BYTES)
61#if defined(__APPLE__) && defined(__aarch64__)
62 #define DT_CACHELINE_BYTES 128
63 #define DT_CACHELINE_FLOATS 32
64 #define DT_CACHELINE_PIXELS 8
66 #define DT_CACHELINE_BYTES 64
67 #define DT_CACHELINE_FLOATS 16
68 #define DT_CACHELINE_PIXELS 4
80#define DT_ALIGNED_ARRAY __attribute__((aligned(DT_CACHELINE_BYTES)))
85#define DT_ALIGNED_PIXEL __attribute__((aligned(16)))
88static inline gboolean
dt_is_aligned(
const void *pointer,
size_t byte_count)
90 return (uintptr_t)pointer % byte_count == 0;
102 return ((
size % alignment) == 0) ?
size : ((
size - 1) / alignment + 1) * alignment;
126#if defined(__FreeBSD_version) && __FreeBSD_version < 700013
127 return malloc(aligned_size);
129 return _aligned_malloc(aligned_size, alignment);
132 if(posix_memalign(&ptr, alignment, aligned_size))
return NULL;
171#define dt_free(ptr) \
172 if(!IS_NULL_PTR(ptr)) \
174 g_free((void *)(ptr)); \
175 *(void **)(&(ptr)) = NULL; \
214#define dt_free_align(ptr) \
215 if(!IS_NULL_PTR(ptr)) \
217 dt_free_align_ptr((void *)(ptr)); \
218 *(void **)(&(ptr)) = NULL; \
228 if(buf) memset(buf, 0,
size);
243 float *
const buf = (
float*)
dt_alloc_align(pixels *
sizeof(
float));
244 if(buf) memset(buf, 0, pixels *
sizeof(
float));
274 for(
size_t k = 0;
k <
size /
sizeof(
unsigned char);
k++) {
275 unsigned char *
const item = (
unsigned char *
const)buffer +
k;
float *const restrict const size_t k
static void memset_zero(void *const buffer, size_t size)
Set the memory buffer to zero as a pack of unsigned char.
static float * dt_calloc_align_float(size_t pixels)
dt_alloc_align_float() followed by a zero fill.
static void * dt_calloc_align(size_t size)
dt_alloc_align() followed by a zero fill.
static void dt_free_align_ptr(void *mem)
Platform back-end for dt_free_align(). Call dt_free_align() instead: this one takes the pointer by va...
static float * dt_alloc_align_float(size_t pixels)
Allocate pixels floats, cacheline-aligned and marked as such.
static size_t dt_round_size_sse(const size_t size)
Round size up to the next multiple of 64.
static void * dt_check_sse_aligned(void *pointer)
Runtime-checked counterpart to DT_IS_ALIGNED().
static void * dt_alloc_align_internal(size_t size)
Platform back-end for dt_alloc_align(). Call dt_alloc_align() instead.
static void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
void * dt_alloc_align(size_t size)
Allocate cacheline-aligned memory.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
static size_t dt_round_size(const size_t size, const size_t alignment)
Round size UP to the next multiple of alignment.
static gboolean dt_is_aligned(const void *pointer, size_t byte_count)
Is pointer aligned on a byte_count boundary? Pure test, no side effect.
#define DT_CACHELINE_BYTES