# `./fio-stl/010 mem.h`

50 public symbols.

### Macros

#### `FIO_MEMORY_ALIGN_LOG`

```c
#define FIO_MEMORY_ALIGN_LOG 6
```

Allocation alignment, MUST be >= 3 and <= 10

_Symbol type:_ `macro`

#### `FIO_MEMORY_ALIGN_SIZE`

```c
#define FIO_MEMORY_ALIGN_SIZE (1UL << (FIO_MEMORY_ALIGN_LOG))
```

The minimal allocation size & alignment.

_Symbol type:_ `macro`

#### `FIO_MEMORY_SYS_ALLOCATION_SIZE_LOG`

```c
#define FIO_MEMORY_SYS_ALLOCATION_SIZE_LOG 21
```

The logarithmic size of a single allocation "chunk" (16 blocks).

Limited to >=17 and <=24.

By default 21, which is a ~2Mb allocation per system call, resulting in a
maximum allocation size of 64Kb.

_Symbol type:_ `macro`

#### `FIO_MEMORY_CACHE_SLOTS`

```c
#define FIO_MEMORY_CACHE_SLOTS 4
```

The number of system allocation "chunks" to cache even if they are not in
use.

_Symbol type:_ `macro`

#### `FIO_MEMORY_INITIALIZE_ALLOCATIONS`

```c
#define FIO_MEMORY_INITIALIZE_ALLOCATIONS   \
  FIO_MEMORY_INITIALIZE_ALLOCATIONS_DEFAULT
```

Forces the allocator to zero out memory early and often, so allocations
return initialized memory (bytes are all zeros).

This will make the realloc2 safe for use (all data not copied is zero).

_Symbol type:_ `macro`

#### `FIO_MEMORY_BLOCKS_PER_ALLOCATION_LOG`

```c
#define FIO_MEMORY_BLOCKS_PER_ALLOCATION_LOG 2
```

The number of blocks per system allocation.

More blocks protect against fragmentation, but lower the maximum number that
can be allocated without reverting to mmap.

Range: 0-4
Recommended: depends on object allocation sizes, usually 1 or 2.

_Symbol type:_ `macro`

#### `FIO_MEMORY_ENABLE_BIG_ALLOC`

```c
#define FIO_MEMORY_ENABLE_BIG_ALLOC 1
```

Uses a whole system allocation to support bigger allocations.

Could increase fragmentation costs.

_Symbol type:_ `macro`

#### `FIO_MEMORY_ARENA_COUNT`

```c
#define FIO_MEMORY_ARENA_COUNT -1
```

Memory arenas mitigate thread contention while using more memory.

Note that at some point arenas are statistically irrelevant... except when
benchmarking contention in multi-core machines.

Negative values will result in dynamic selection based on CPU core count.

_Symbol type:_ `macro`

#### `FIO_MEMORY_ARENA_COUNT_FALLBACK`

```c
#define FIO_MEMORY_ARENA_COUNT_FALLBACK 24
```



_Symbol type:_ `macro`

#### `FIO_MEMORY_ARENA_COUNT_MAX`

```c
#define FIO_MEMORY_ARENA_COUNT_MAX 64
```



_Symbol type:_ `macro`

#### `FIO_MEMORY_USE_THREAD_MUTEX`

```c
#define FIO_MEMORY_USE_THREAD_MUTEX 1
```

If arena count isn't linked to the CPU count, threads might busy-spin.
It is better to slow wait than fast busy spin when the work in the lock is
longer... and system allocations are performed inside arena locks.

_Symbol type:_ `macro`

#### `FIO_MEMORY_BLOCKS_PER_ALLOCATION`

```c
#define FIO_MEMORY_BLOCKS_PER_ALLOCATION   \
  (1UL << FIO_MEMORY_BLOCKS_PER_ALLOCATION_LOG)
```

the number of allocation blocks per system allocation.

_Symbol type:_ `macro`

#### `FIO_MEMORY_SYS_ALLOCATION_SIZE`

```c
#define FIO_MEMORY_SYS_ALLOCATION_SIZE   \
  (1UL << FIO_MEMORY_SYS_ALLOCATION_SIZE_LOG)
```

the total number of bytes consumed per system allocation.

_Symbol type:_ `macro`

#### `FIO_MEMORY_BLOCK_ALLOC_LIMIT`

```c
#define FIO_MEMORY_BLOCK_ALLOC_LIMIT   \
  (FIO_MEMORY_SYS_ALLOCATION_SIZE >> (FIO_MEMORY_BLOCKS_PER_ALLOCATION_LOG + 2))
```

The maximum allocation size, after which a big/system allocation is used.

_Symbol type:_ `macro`

#### `FIO_MEMORY_BIG_ALLOC_LIMIT`

```c
#define FIO_MEMORY_BIG_ALLOC_LIMIT   \
  (FIO_MEMORY_SYS_ALLOCATION_SIZE >>   \
   (FIO_MEMORY_BLOCKS_PER_ALLOCATION_LOG > 3   \
        ? 3   \
        : FIO_MEMORY_BLOCKS_PER_ALLOCATION_LOG))
```

the limit of a big allocation, if enabled

_Symbol type:_ `macro`

#### `FIO_MEMORY_ALLOC_LIMIT`

```c
#define FIO_MEMORY_ALLOC_LIMIT FIO_MEMORY_BIG_ALLOC_LIMIT
```



_Symbol type:_ `macro`

#### `FIO_MEM_BYTES2PAGES`

```c
#define FIO_MEM_BYTES2PAGES(size)   \
  ((size > (SIZE_MAX - ((1UL << FIO_MEM_PAGE_SIZE_LOG) - 1)))   \
       ? size   \
       : (((size_t)(size) + ((1UL << FIO_MEM_PAGE_SIZE_LOG) - 1)) &   \
          ((~(size_t)0) << FIO_MEM_PAGE_SIZE_LOG)))
```



_Symbol type:_ `macro`

#### `FIO_PAGE_ALIGN`

```c
#define FIO_PAGE_ALIGN   \
  __attribute__((assume_aligned((1UL << FIO_MEM_PAGE_SIZE_LOG))))
```



_Symbol type:_ `macro`

#### `FIO_PAGE_ALIGN_NEW`

```c
#define FIO_PAGE_ALIGN_NEW   \
  __attribute__((malloc, assume_aligned((1UL << FIO_MEM_PAGE_SIZE_LOG))))
```



_Symbol type:_ `macro`

#### `FIO_MEMORY_HEADER_SIZE`

```c
#define FIO_MEMORY_HEADER_SIZE   \
  ((sizeof(FIO_NAME(FIO_MEMORY_NAME, __mem_chunk_s)) +   \
    (FIO_MEMORY_ALIGN_SIZE - 1)) &   \
   (~(FIO_MEMORY_ALIGN_SIZE - 1)))
```



_Symbol type:_ `macro`

#### `FIO_MEMORY_UNITS_PER_BLOCK`

```c
#define FIO_MEMORY_UNITS_PER_BLOCK   \
  (FIO_MEMORY_BLOCK_SIZE / FIO_MEMORY_ALIGN_SIZE)
```



_Symbol type:_ `macro`

#### `FIO_MEMORY_STATE_SIZE`

```c
#define FIO_MEMORY_STATE_SIZE(arena_count)   \
  FIO_MEM_BYTES2PAGES(   \
      (sizeof(*FIO_NAME(FIO_MEMORY_NAME, __mem_state)) +   \
       (sizeof(FIO_NAME(FIO_MEMORY_NAME, __mem_arena_s)) * (arena_count))))
```



_Symbol type:_ `macro`

#### `FIO_MEMORY_BIG_BLOCK_MARKER`

```c
#define FIO_MEMORY_BIG_BLOCK_MARKER ((~(uint32_t)0) << 2)
```



_Symbol type:_ `macro`

#### `FIO_MEMORY_BIG_BLOCK_HEADER_SIZE`

```c
#define FIO_MEMORY_BIG_BLOCK_HEADER_SIZE   \
  (((sizeof(FIO_NAME(FIO_MEMORY_NAME, __mem_big_block_s)) +   \
     ((FIO_MEMORY_ALIGN_SIZE - 1))) &   \
    ((~(0UL)) << FIO_MEMORY_ALIGN_LOG)))
```



_Symbol type:_ `macro`

#### `FIO_MEMORY_BIG_BLOCK_SIZE`

```c
#define FIO_MEMORY_BIG_BLOCK_SIZE   \
  (FIO_MEMORY_SYS_ALLOCATION_SIZE - FIO_MEMORY_BIG_BLOCK_HEADER_SIZE)
```



_Symbol type:_ `macro`

#### `FIO_MEMORY_UNITS_PER_BIG_BLOCK`

```c
#define FIO_MEMORY_UNITS_PER_BIG_BLOCK   \
  (FIO_MEMORY_BIG_BLOCK_SIZE / FIO_MEMORY_ALIGN_SIZE)
```



_Symbol type:_ `macro`

#### `FIO_TEST_MULTI_THREADED`

```c
#define FIO_TEST_MULTI_THREADED 0
```



_Symbol type:_ `macro`

### Functions

#### `fio_malloc`

```c
void *FIO_MEM_ALIGN_NEW fio_malloc(size_t size)
```

Allocates memory using a per-CPU core block memory pool.
Memory is zeroed out.

Allocations above FIO_MEMORY_BLOCK_ALLOC_LIMIT will be redirected to `mmap`,
as if `mempool_mmap` was called.

`mempool_malloc` promises a best attempt at providing locality between
consecutive calls, but locality can't be guaranteed.

_Symbol type:_ `function`

#### `fio_calloc`

```c
void *FIO_MEM_ALIGN_NEW fio_calloc(size_t size_per_unit, size_t unit_count)
```

same as calling `fio_malloc(size_per_unit * unit_count)`;

Allocations above FIO_MEMORY_BLOCK_ALLOC_LIMIT will be redirected to `mmap`,
as if `mempool_mmap` was called.

_Symbol type:_ `function`

#### `fio_free`

```c
void fio_free(void *ptr)
```

Frees memory that was allocated using this library.

_Symbol type:_ `function`

#### `fio_realloc`

```c
void *FIO_MEM_ALIGN fio_realloc(void *ptr, size_t new_size)
```

Re-allocates memory. An attempt to avoid copying the data is made only for
big memory allocations (larger than FIO_MEMORY_BLOCK_ALLOC_LIMIT).

_Symbol type:_ `function`

#### `fio_realloc2`

```c
void *FIO_MEM_ALIGN fio_realloc2(void *ptr, size_t new_size, size_t copy_len)
```

Re-allocates memory. An attempt to avoid copying the data is made only for
big memory allocations (larger than FIO_MEMORY_BLOCK_ALLOC_LIMIT).

This variation can perform better, as it might copy less data.

_Symbol type:_ `function`

#### `fio_realloc_aligned`

```c
void *FIO_MEM_ALIGN fio_realloc_aligned(void *ptr, size_t new_size, size_t copy_len, size_t alignment)
```

Re-allocates memory, enforcing a minimum pointer alignment.

This is the core of the aligned allocation API: `malloc_aligned` and
`calloc_aligned` simply route to this function with a NULL `ptr`.

The `alignment` argument is normalized as follows:

- `0` is treated as the allocator's default (`FIO_MEMORY_ALIGN_SIZE`);
- non power-of-2 values are rounded DOWN to the nearest power of 2;
- the effective alignment is the maximum of the requested alignment, the
  current alignment of `ptr` (if any) and `FIO_MEMORY_ALIGN_SIZE`;
- effective values above `FIO_MEMORY_SYS_ALLOCATION_SIZE` fail
  (returns NULL, sets `errno` to `EINVAL`).

Data preservation semantics are identical to `realloc2` (`copy_len` bytes).
In-place growth may only occur when the existing pointer already satisfies
the requested alignment.

_Symbol type:_ `function`

#### `fio_malloc_aligned`

```c
void *FIO_MEM_ALIGN_NEW fio_malloc_aligned(size_t size, size_t alignment)
```

Allocates `size` bytes, returning a pointer aligned to (at least)
`alignment`. Same semantics as `realloc_aligned(NULL, size, 0, alignment)`.

_Symbol type:_ `function`

#### `fio_calloc_aligned`

```c
void *FIO_MEM_ALIGN_NEW fio_calloc_aligned(size_t size_per_unit, size_t unit_count, size_t alignment)
```

Same as `malloc_aligned(size_per_unit * unit_count, alignment)`,
except that the allocated memory is zeroed out.

_Symbol type:_ `function`

#### `fio_mmap`

```c
void *FIO_MEM_ALIGN_NEW fio_mmap(size_t size)
```

Allocates memory directly using `mmap`, this is preferred for objects that
both require almost a page of memory (or more) and expect a long lifetime.

However, since this allocation will invoke the system call (`mmap`), it will
be inherently slower.

`mempoll_free` can be used for deallocating the memory.

_Symbol type:_ `function`

#### `fio_malloc_after_fork`

```c
void fio_malloc_after_fork(void)
```

When forking is called manually, call this function to reset the facil.io
memory allocator's locks.

This is provided in case of forking in a multi-threaded environment, which
some people do even though it's bad.

_Symbol type:_ `function`

#### `fio_malloc_arenas`

```c
size_t fio_malloc_arenas(void)
```

Arena count for the allocator.

_Symbol type:_ `function`

#### `fio_malloc_block_size`

```c
size_t fio_malloc_block_size(void)
```



_Symbol type:_ `function`

#### `fio_malloc_print_state`

```c
void fio_malloc_print_state(void)
```

Prints the allocator's data structure. May be used for debugging.

_Symbol type:_ `function`

#### `fio_malloc_print_free_block_list`

```c
void fio_malloc_print_free_block_list(void)
```

Prints the allocator's free block list. May be used for debugging.

_Symbol type:_ `function`

#### `fio_malloc_print_settings`

```c
void fio_malloc_print_settings(void)
```

Prints the settings used to define the allocator.

_Symbol type:_ `function`

#### `fio_malloc_sys_alloc_size`

```c
inline size_t fio_malloc_sys_alloc_size(void)
```

System allocation sizes (bytes per system allocation).

_Symbol type:_ `function`

#### `fio_malloc_cache_slots`

```c
inline size_t fio_malloc_cache_slots(void)
```

Cached system allocations (free, but held on to).

_Symbol type:_ `function`

#### `fio_malloc_alignment`

```c
inline size_t fio_malloc_alignment(void)
```

Allocations alignment.

_Symbol type:_ `function`

#### `fio_malloc_alignment_log`

```c
inline size_t fio_malloc_alignment_log(void)
```

Allocations alignment log (base 2).

_Symbol type:_ `function`

#### `fio_malloc_alloc_limit`

```c
inline size_t fio_malloc_alloc_limit(void)
```

Allocation limit (at which point do we switch to system allocations?).

_Symbol type:_ `function`

#### `fio_malloc_arena_alloc_limit`

```c
inline size_t fio_malloc_arena_alloc_limit(void)
```

Allocation limit for arena based allocation (vs. big allocations).

_Symbol type:_ `function`

#### `fio_realloc_is_safe`

```c
inline size_t fio_realloc_is_safe(void)
```



_Symbol type:_ `function`

#### `fio_alloc_size`

```c
inline size_t fio_alloc_size(size_t minimum_bytes)
```

Returns the number of usable bytes the allocator will actually reserve for
an allocation request of `minimum_bytes` (the allocation's size class).

The result is alignment agnostic - alignment padding, if any, is reserved
in addition to the returned value.

NOTE: when the custom allocator is bypassed (`FIO_MEMORY_DISABLE`), the
system allocator exposes no rounding guarantee and `minimum_bytes` is
returned unchanged.

_Symbol type:_ `function`

-----------------------------------------------------
