align.h#

#include <sif/utils/align.h>
SIF_UTILS_ALIGN_H#

Cache-line aligned allocation.

Every bulk buffer in sif comes from here rather than from malloc. Two reasons: the vectorized loops want their operands aligned, and blocks handed to different OpenMP threads must not share a cache line, or the threads serialize on the coherence protocol while appearing to touch separate data.

Allocations are therefore both aligned to #SIF_CACHE_LINE and rounded up to a whole number of cache lines, so two adjacent allocations can never share one.

Warning

Memory from these functions must be released with sif_free_aligned(), never with free().

SIF_ASSUME_ALIGNED(ptr)#

Tell the compiler a pointer is cache-line aligned.

SIF_ALIGNED_FN#

Mark a function as returning fresh, cache-line aligned memory.

void *sif_malloc_aligned(size_t size)#

Allocate aligned, uninitialized memory.

Parameters:
  • size – Number of bytes required.

Returns:

Pointer to the block, owned by the caller and released with sif_free_aligned(). NULL on failure, and also when size is 0.

void *sif_calloc_aligned(size_t count, size_t size)#

Allocate aligned, zero-initialized memory.

Parameters:
  • count – Number of elements.

  • size – Size of each element, in bytes.

Returns:

Pointer to the zeroed block, owned by the caller and released with sif_free_aligned(). NULL on failure.

void *sif_realloc_aligned(void *ptr, size_t old_size, size_t new_size)#

Resize an aligned block, preserving its contents.

Unlike realloc() this always allocates a new block and copies – alignment cannot be preserved by growing in place – so it costs a full copy every time. Prefer sizing the buffer correctly over growing it in a loop.

Passing NULL for ptr allocates; passing 0 for new_size frees and returns NULL. On failure the original block is left untouched, so assigning the result straight back to ptr leaks it.

Parameters:
  • ptr – Block to resize, or NULL.

  • old_size – Current size of ptr in bytes.

  • new_size – Requested size in bytes. Content beyond it is discarded.

Returns:

The new block, or NULL on failure.

Warning

old_size is trusted, not checked. Passing a value larger than the real allocation reads past its end.

void sif_free_aligned(void *ptr)#

Release a block from one of the allocators above.

Parameters:
  • ptr – Block to free. NULL is accepted and ignored.