1#define _POSIX_C_SOURCE 200809L
126#include "rte/oal/memory/rte_mem_util.h"
131 rte_task_config_t config;
133 volatile sig_atomic_t should_stop;
134 rte_task_handle_t self_handle;
139typedef char posix_task_storage_fits_[(
sizeof(
posix_task_state_t) <=
sizeof(rte_task_storage_t)) ? 1 : -1];
144static pthread_key_t s_task_key;
145static bool s_task_key_ready =
false;
154 bool applied =
false;
155 int min_prio = sched_get_priority_min(SCHED_FIFO);
156 int max_prio = sched_get_priority_max(SCHED_FIFO);
158 if ((min_prio >= 0) && (max_prio >= min_prio))
160 struct sched_param sched;
163 if (priority < (uint32_t)min_prio)
167 else if (priority > (uint32_t)max_prio)
173 wanted = (int)priority;
176 rte_mem_set(&sched, 0,
sizeof(sched));
177 sched.sched_priority = wanted;
178 if (pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED) == 0)
180 if (pthread_attr_setschedpolicy(attr, SCHED_FIFO) == 0)
182 if (pthread_attr_setschedparam(attr, &sched) == 0)
196 s_task_key_ready = (pthread_key_create(&s_task_key, NULL) == 0);
203 static pthread_once_t key_once = PTHREAD_ONCE_INIT;
208 ready = s_task_key_ready;
218 struct timespec deadline;
220 bool clock_failed = !running;
222 while (running && (state->should_stop == 0))
230 else if (state->should_stop == 0)
232 state->config.entry(state->config.user_ctx);
244 POSIX_OSA_REPORT_RT_ATTRIBUTE(
"task monotonic clock failed - task stopped");
251 if (state->config.period_ms == 0U)
270 state->config.entry(state->config.user_ctx);
284 if (pthread_setspecific(s_task_key, state) == 0)
292 POSIX_OSA_REPORT_RT_ATTRIBUTE(
"task thread-specific data not set - task not run");
302 return (pthread_getspecific(s_task_key) == (
const void *)state);
310 rte_status_t status = RTE_STATUS_OK;
315 if (pthread_join(state->thread, NULL) == 0)
317 state->joinable =
false;
321 status = RTE_STATUS_INTERNAL_ERROR;
332 rte_status_t status = RTE_STATUS_INTERNAL_ERROR;
335 if (pthread_attr_init(&attr) == 0)
337 bool inherit_fallback =
false;
340 if (state->config.stack_size > 0U)
342 if (pthread_attr_setstacksize(&attr, state->config.stack_size) != 0)
345 POSIX_OSA_REPORT_RT_ATTRIBUTE(
"task stack size not applied");
355 inherit_fallback =
true;
360 inherit_fallback =
true;
363 if (inherit_fallback)
367 POSIX_OSA_REPORT_RT_ATTRIBUTE(
"task SCHED_FIFO priority not applied");
369 if (pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) == 0)
377 status = RTE_STATUS_OK;
379 (void)pthread_attr_destroy(&attr);
384static rte_status_t
osadapter_create(rte_task_storage_t *storage,
const rte_task_config_t *config,
385 rte_task_handle_t *out_handle)
390 if ((storage == NULL) || (config == NULL) || (out_handle == NULL) || (config->entry == NULL))
392 return RTE_STATUS_INVALID_PARAM;
403 return RTE_STATUS_INTERNAL_ERROR;
407 rte_mem_set(state, 0,
sizeof(*state));
408 state->config = *config;
409 state->self_handle = (rte_task_handle_t)(
void *)storage;
410 *out_handle = state->self_handle;
411 return RTE_STATUS_OK;
414static rte_status_t osadapter_suspend(rte_task_handle_t handle)
421 return RTE_STATUS_INVALID_PARAM;
430 status = RTE_STATUS_OK;
439static rte_status_t osadapter_start(rte_task_handle_t handle)
446 return RTE_STATUS_INVALID_PARAM;
453 status = RTE_STATUS_NOT_SUPPORTED;
460 if (status == RTE_STATUS_OK)
462 state->should_stop = 0;
464 if (status == RTE_STATUS_OK)
466 state->joinable =
true;
473static rte_status_t osadapter_destroy(rte_task_handle_t handle)
475 return osadapter_suspend(handle);
478static const rte_osadapter_task_t s_posix_task_osadapter = {
osadapter_create, osadapter_start, osadapter_suspend,
483 return &s_posix_task_osadapter;
Real POSIX/Linux OSAdapter for every OAL service (ADR-018).
const rte_osadapter_task_t * rte_posix_osadapter_task(void)
The POSIX rte_task OSAdapter (one pthread per task).
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_period_init(struct timespec *out_deadline)
Starts a period: reads CLOCK_MONOTONIC into the deadline.
void posix_period_wake_all(volatile sig_atomic_t *should_stop)
Requests a stop of a periodic thread and wakes it from its wait.
bool posix_period_wake_ready(void)
Creates the process-wide wake object on the first call; true once it exists.
rte_status_t posix_period_sleep_until(const struct timespec *deadline, const volatile sig_atomic_t *should_stop)
Waits until the absolute CLOCK_MONOTONIC deadline, or until a stop is requested.
void posix_period_advance(struct timespec *deadline, rte_duration_ms_t period_ms)
Moves the deadline one period later, keeping tv_nsec in [0, 1 s).
Private helper: pacing of a periodic thread by an absolute CLOCK_MONOTONIC deadline (OSA rule R3),...
Private helper: reports a real-time attribute this OSAdapter could not apply (OSA rules R1/R2/R6).
static void create_task_key(void)
static rte_status_t join_task_thread(posix_task_state_t *state)
static bool set_fifo_attributes(pthread_attr_t *attr, uint32_t priority)
static bool is_task_thread(const posix_task_state_t *state)
static void * task_thread_main(void *arg)
static void run_task(posix_task_state_t *state)
static bool task_key_ready(void)
static void run_periodic_task(posix_task_state_t *state)
static rte_status_t create_task_thread(posix_task_state_t *state)