4#define _POSIX_C_SOURCE 200809L
55#include "rte/utils/cast/rte_cast.h"
61#include "rte/oal/memory/rte_mem_util.h"
64#ifndef RTE_POSIX_MEM_ARENA_SIZE
65#define RTE_POSIX_MEM_ARENA_SIZE (1024U * 1024U)
70#ifndef RTE_POSIX_MEM_LOCK_TIMEOUT_MS
71#define RTE_POSIX_MEM_LOCK_TIMEOUT_MS 50U
86typedef char posix_mem_pool_storage_fits_[(
sizeof(
posix_mem_pool_state_t) <=
sizeof(rte_mem_pool_storage_t)) ? 1
90static rte_status_t
osadapter_create(rte_mem_pool_storage_t *storage,
const rte_mem_pool_config_t *config,
91 rte_mem_pool_handle_t *out_handle);
92static rte_status_t osadapter_acquire(rte_mem_pool_handle_t handle,
void **out_block);
94static rte_status_t osadapter_release(rte_mem_pool_handle_t handle,
void *block);
95static rte_status_t osadapter_stats(rte_mem_pool_handle_t handle,
size_t *out_free_blocks,
size_t *out_used_blocks);
96static rte_status_t mem_lock(
void);
100static size_t g_arena_used = 0U;
101static pthread_mutex_t g_mem_lock;
102static bool g_mem_initialised =
false;
103static const rte_osadapter_memory_t s_posix_memory_osadapter = {
osadapter_create, osadapter_acquire, osadapter_release,
112 return &s_posix_memory_osadapter;
117 rte_status_t status = RTE_STATUS_OK;
118 pthread_mutexattr_t attr;
120 if (!g_mem_initialised)
125 if (pthread_mutexattr_init(&attr) != 0)
127 status = RTE_STATUS_INTERNAL_ERROR;
131 if (pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT) != 0)
133 status = RTE_STATUS_INTERNAL_ERROR;
135 else if (pthread_mutex_init(&g_mem_lock, &attr) != 0)
137 status = RTE_STATUS_INTERNAL_ERROR;
143 (void)pthread_mutexattr_destroy(&attr);
146 if (status == RTE_STATUS_OK)
148 g_mem_initialised =
true;
153 POSIX_OSA_REPORT_RT_ATTRIBUTE(
"memory pool lock refused priority inheritance - init failed");
163static rte_status_t
osadapter_create(rte_mem_pool_storage_t *storage,
const rte_mem_pool_config_t *config,
164 rte_mem_pool_handle_t *out_handle)
172 if ((storage == NULL) || (config == NULL) || (out_handle == NULL) || (config->block_size == 0U)
173 || (config->block_count == 0U))
175 return RTE_STATUS_INVALID_PARAM;
177 if (config->block_size <
sizeof(
void *))
179 return RTE_STATUS_INVALID_PARAM;
185 if (rte_cast_checked_mul_size(config->block_size, config->block_count, &total_bytes) != RTE_STATUS_OK)
187 return RTE_STATUS_INVALID_PARAM;
190 if (status != RTE_STATUS_OK)
196 (void)pthread_mutex_unlock(&g_mem_lock);
197 return RTE_STATUS_RESOURCE_EXHAUSTED;
201 g_arena_used += total_bytes;
202 (void)pthread_mutex_unlock(&g_mem_lock);
204 for (i = 0U; i < config->block_count; i++)
206 uint8_t *block = base + (i * config->block_size);
207 void *next = (i + 1U < config->block_count) ? (
void *)(base + ((i + 1U) * config->block_size)) : NULL;
209 rte_mem_copy(block, &next,
sizeof(next));
214 state->block_size = config->block_size;
215 state->block_count = config->block_count;
216 state->free_count = config->block_count;
217 state->free_list_head = (
void *)base;
219 *out_handle = (rte_mem_pool_handle_t)(
void *)storage;
220 return RTE_STATUS_OK;
223static rte_status_t osadapter_acquire(rte_mem_pool_handle_t handle,
void **out_block)
230 if ((state == NULL) || (out_block == NULL))
232 return RTE_STATUS_INVALID_PARAM;
235 if (status != RTE_STATUS_OK)
240 if (state->free_list_head == NULL)
242 (void)pthread_mutex_unlock(&g_mem_lock);
244 return RTE_STATUS_RESOURCE_EXHAUSTED;
247 block = state->free_list_head;
248 rte_mem_copy(&next, block,
sizeof(next));
249 state->free_list_head = next;
250 state->free_count -= 1U;
251 (void)pthread_mutex_unlock(&g_mem_lock);
253 return RTE_STATUS_OK;
258 const uint8_t *b = (
const uint8_t *)block;
261 if ((b < state->base) || (b >= (state->base + (state->block_size * state->block_count))))
265 byte_offset = (size_t)(b - state->base);
266 return (byte_offset % state->block_size) == 0U;
269static rte_status_t osadapter_release(rte_mem_pool_handle_t handle,
void *block)
274 if ((state == NULL) || (block == NULL))
276 return RTE_STATUS_INVALID_PARAM;
278 if (!g_mem_initialised)
280 return RTE_STATUS_INVALID_STATE;
282 if (!block_belongs_to_pool(state, block))
284 return RTE_STATUS_INVALID_PARAM;
288 if (status != RTE_STATUS_OK)
292 rte_mem_copy(block, &state->free_list_head,
sizeof(state->free_list_head));
293 state->free_list_head = block;
294 state->free_count += 1U;
295 (void)pthread_mutex_unlock(&g_mem_lock);
296 return RTE_STATUS_OK;
299static rte_status_t osadapter_stats(rte_mem_pool_handle_t handle,
size_t *out_free_blocks,
size_t *out_used_blocks)
304 if ((state == NULL) || (out_free_blocks == NULL) || (out_used_blocks == NULL))
306 return RTE_STATUS_INVALID_PARAM;
309 if (status != RTE_STATUS_OK)
313 *out_free_blocks = state->free_count;
314 *out_used_blocks = state->block_count - state->free_count;
315 (void)pthread_mutex_unlock(&g_mem_lock);
316 return RTE_STATUS_OK;
323static rte_status_t mem_lock(
void)
327 if (!g_mem_initialised)
329 status = RTE_STATUS_INVALID_STATE;
Real POSIX/Linux OSAdapter for every OAL service (ADR-018).
const rte_osadapter_memory_t * rte_posix_osadapter_memory(void)
The POSIX rte_memory OSAdapter (static arena, no malloc). Its operations return RTE_STATUS_INVALID_ST...
rte_status_t rte_posix_osadapter_memory_init(void)
Creates the memory OSAdapter's pool lock as a priority-inheritance mutex (OSA rule R2,...
static rte_status_t osadapter_create(rte_ipc_storage_t *storage, const rte_ipc_config_t *config, rte_ipc_handle_t *out_handle)
rte_status_t posix_osa_lock_bounded(pthread_mutex_t *mutex, rte_duration_ms_t timeout_ms)
Waits at most timeout_ms for a pthread mutex.
Private helper: a bounded wait for a pthread mutex (OSA rule R2: every wait bounded).
#define RTE_POSIX_MEM_ARENA_SIZE
static uint8_t g_arena[RTE_POSIX_MEM_ARENA_SIZE]
Private helper: reports a real-time attribute this OSAdapter could not apply (OSA rules R1/R2/R6).