34#include "safeapi/utils/cast/sapi_cast.h"
37#include "safeapi/oal/memory/sapi_mem_util.h"
40#ifndef SAPI_POSIX_MEM_ARENA_SIZE
41#define SAPI_POSIX_MEM_ARENA_SIZE (1024U * 1024U)
56typedef char posix_mem_pool_storage_fits_[(
sizeof(
posix_mem_pool_state_t) <=
sizeof(sapi_mem_pool_storage_t)) ? 1
60static sapi_status_t backend_create(sapi_mem_pool_storage_t *storage,
const sapi_mem_pool_config_t *config,
61 sapi_mem_pool_handle_t *out_handle);
62static sapi_status_t backend_acquire(sapi_mem_pool_handle_t handle,
void **out_block);
64static sapi_status_t backend_release(sapi_mem_pool_handle_t handle,
void *block);
65static sapi_status_t backend_stats(sapi_mem_pool_handle_t handle,
size_t *out_free_blocks,
size_t *out_used_blocks);
69static size_t g_arena_used = 0U;
70static const sapi_mem_pool_backend_t s_posix_memory_backend = { backend_create, backend_acquire, backend_release,
79 return &s_posix_memory_backend;
85static sapi_status_t backend_create(sapi_mem_pool_storage_t *storage,
const sapi_mem_pool_config_t *config,
86 sapi_mem_pool_handle_t *out_handle)
93 if ((storage == NULL) || (config == NULL) || (out_handle == NULL) || (config->block_size == 0U)
94 || (config->block_count == 0U))
96 return SAPI_STATUS_INVALID_PARAM;
98 if (config->block_size <
sizeof(
void *))
100 return SAPI_STATUS_INVALID_PARAM;
106 if (sapi_cast_checked_mul_size(config->block_size, config->block_count, &total_bytes) != SAPI_STATUS_OK)
108 return SAPI_STATUS_INVALID_PARAM;
112 return SAPI_STATUS_RESOURCE_EXHAUSTED;
116 g_arena_used += total_bytes;
118 for (i = 0U; i < config->block_count; i++)
120 uint8_t *block = base + (i * config->block_size);
121 void *next = (i + 1U < config->block_count) ? (
void *)(base + ((i + 1U) * config->block_size)) : NULL;
123 sapi_mem_copy(block, &next,
sizeof(next));
128 state->block_size = config->block_size;
129 state->block_count = config->block_count;
130 state->free_count = config->block_count;
131 state->free_list_head = (
void *)base;
133 *out_handle = (sapi_mem_pool_handle_t)(
void *)storage;
134 return SAPI_STATUS_OK;
137static sapi_status_t backend_acquire(sapi_mem_pool_handle_t handle,
void **out_block)
143 if ((state == NULL) || (out_block == NULL))
145 return SAPI_STATUS_INVALID_PARAM;
147 if (state->free_list_head == NULL)
150 return SAPI_STATUS_RESOURCE_EXHAUSTED;
153 block = state->free_list_head;
154 sapi_mem_copy(&next, block,
sizeof(next));
155 state->free_list_head = next;
156 state->free_count -= 1U;
158 return SAPI_STATUS_OK;
163 const uint8_t *b = (
const uint8_t *)block;
166 if ((b < state->base) || (b >= (state->base + (state->block_size * state->block_count))))
170 byte_offset = (size_t)(b - state->base);
171 return (byte_offset % state->block_size) == 0U;
174static sapi_status_t backend_release(sapi_mem_pool_handle_t handle,
void *block)
178 if ((state == NULL) || (block == NULL))
180 return SAPI_STATUS_INVALID_PARAM;
182 if (!block_belongs_to_pool(state, block))
184 return SAPI_STATUS_INVALID_PARAM;
187 sapi_mem_copy(block, &state->free_list_head,
sizeof(state->free_list_head));
188 state->free_list_head = block;
189 state->free_count += 1U;
190 return SAPI_STATUS_OK;
193static sapi_status_t backend_stats(sapi_mem_pool_handle_t handle,
size_t *out_free_blocks,
size_t *out_used_blocks)
197 if ((state == NULL) || (out_free_blocks == NULL) || (out_used_blocks == NULL))
199 return SAPI_STATUS_INVALID_PARAM;
201 *out_free_blocks = state->free_count;
202 *out_used_blocks = state->block_count - state->free_count;
203 return SAPI_STATUS_OK;
Real POSIX/Linux backend for every OAL service (ADR-018).
const sapi_mem_pool_backend_t * sapi_posix_backend_memory(void)
The POSIX sapi_memory backend (static arena, no malloc).
#define SAPI_POSIX_MEM_ARENA_SIZE
static uint8_t g_arena[SAPI_POSIX_MEM_ARENA_SIZE]