RTE OSAdapter POSIX 0.1.0 build 41b3eb3
POSIX/Linux OAL OSAdapter for Platform_RTE
Loading...
Searching...
No Matches
rte_posix_osadapter_period.c File Reference

Pacing of a periodic thread by an absolute CLOCK_MONOTONIC deadline (OSA rule R3), shared by the timer OSAdapter's thread loop and the task OSAdapter's periodic loop, and its wake-up by a stop (OSA rule R2, audit item 7b-1). Semantics, the two host variants, why no wake-up is lost and the known limits are documented in rte_posix_osadapter_period.h. Replaces the per-file ms_to_timespec() / timespec_add_ms() copies of rte_posix_osadapter_timer.c and rte_posix_osadapter_task.c (2026-10-04): before, a non-Linux host slept a fresh relative period after every callback (the period drifted by the callback's run time) and a failed first clock read on Linux started the deadline at 0. Before 7b-1 (2026-10-04) the wait was a clock_nanosleep() (Linux) / nanosleep() (other hosts) that a stop could not interrupt, so stop, suspend and destroy waited up to one period for the thread to see its stop flag. More...

#include "rte_posix_osadapter_period.h"
#include "rte_posix_osadapter_lock.h"
#include "rte_posix_osadapter_report.h"
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>
Include dependency graph for rte_posix_osadapter_period.c:

Go to the source code of this file.

Macros

#define _POSIX_C_SOURCE   200809L
#define POSIX_PERIOD_NS_PER_MS   1000000L
#define POSIX_PERIOD_NS_PER_S   1000000000L
#define POSIX_PERIOD_WAIT_FAILED   (-1)
#define RTE_POSIX_PERIOD_WAKE_LOCK_TIMEOUT_MS   50U

Functions

static void create_wake_object (void)
static bool set_wake_clock (pthread_condattr_t *attr)
static bool time_left_ns (const struct timespec *deadline, int64_t *out_ns)
static rte_duration_ms_t ns_to_ms_rounded_up (int64_t ns)
static rte_status_t wait_to_deadline (const struct timespec *deadline, const volatile sig_atomic_t *should_stop)
static rte_status_t wait_locked (const struct timespec *deadline, const volatile sig_atomic_t *should_stop, bool *out_waiting)
static int wait_for_wake (const struct timespec *deadline)
rte_status_t posix_period_init (struct timespec *out_deadline)
 Starts a period: reads CLOCK_MONOTONIC into the deadline.
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).
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.
bool posix_period_wake_ready (void)
 Creates the process-wide wake object on the first call; true once it exists.
void posix_period_wake_all (volatile sig_atomic_t *should_stop)
 Requests a stop of a periodic thread and wakes it from its wait.

Variables

static pthread_mutex_t s_wake_lock
static pthread_cond_t s_wake_cond
static bool s_wake_ready = false

Detailed Description

Pacing of a periodic thread by an absolute CLOCK_MONOTONIC deadline (OSA rule R3), shared by the timer OSAdapter's thread loop and the task OSAdapter's periodic loop, and its wake-up by a stop (OSA rule R2, audit item 7b-1). Semantics, the two host variants, why no wake-up is lost and the known limits are documented in rte_posix_osadapter_period.h. Replaces the per-file ms_to_timespec() / timespec_add_ms() copies of rte_posix_osadapter_timer.c and rte_posix_osadapter_task.c (2026-10-04): before, a non-Linux host slept a fresh relative period after every callback (the period drifted by the callback's run time) and a failed first clock read on Linux started the deadline at 0. Before 7b-1 (2026-10-04) the wait was a clock_nanosleep() (Linux) / nanosleep() (other hosts) that a stop could not interrupt, so stop, suspend and destroy waited up to one period for the thread to see its stop flag.

Definition in file rte_posix_osadapter_period.c.

Macro Definition Documentation

◆ _POSIX_C_SOURCE

#define _POSIX_C_SOURCE   200809L

Definition at line 4 of file rte_posix_osadapter_period.c.

◆ POSIX_PERIOD_NS_PER_MS

#define POSIX_PERIOD_NS_PER_MS   1000000L

Local makros

Definition at line 34 of file rte_posix_osadapter_period.c.

◆ POSIX_PERIOD_NS_PER_S

#define POSIX_PERIOD_NS_PER_S   1000000000L

Definition at line 35 of file rte_posix_osadapter_period.c.

◆ POSIX_PERIOD_WAIT_FAILED

#define POSIX_PERIOD_WAIT_FAILED   (-1)

Definition at line 38 of file rte_posix_osadapter_period.c.

◆ RTE_POSIX_PERIOD_WAKE_LOCK_TIMEOUT_MS

#define RTE_POSIX_PERIOD_WAKE_LOCK_TIMEOUT_MS   50U

Definition at line 43 of file rte_posix_osadapter_period.c.

Function Documentation

◆ create_wake_object()

void create_wake_object ( void )
static

Local types declarations Local function declarations

pthread_once() routine: creates the wake mutex (priority inheritance) and condition variable, or reports the refusal once and leaves s_wake_ready false (see posix_period_wake_ready() in the header).

Definition at line 167 of file rte_posix_osadapter_period.c.

◆ ns_to_ms_rounded_up()

rte_duration_ms_t ns_to_ms_rounded_up ( int64_t ns)
static

A positive time in ns as whole ms, rounded up (a lock bound never ends before the deadline), capped at the largest rte_duration_ms_t.

Definition at line 245 of file rte_posix_osadapter_period.c.

◆ posix_period_advance()

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).

Pure arithmetic on the deadline, no clock read. A NULL deadline is ignored.

Parameters
deadlineDeadline from posix_period_init() (normalised). Updated in place.
period_msPeriod to add, in milliseconds.
Returns
None.

Definition at line 92 of file rte_posix_osadapter_period.c.

◆ posix_period_init()

rte_status_t posix_period_init ( struct timespec * out_deadline)

Starts a period: reads CLOCK_MONOTONIC into the deadline.

Global variables declarations Global functions

Called once by the periodic thread when it starts; the first expiry is one posix_period_advance() later.

Parameters
out_deadlineReceives the current CLOCK_MONOTONIC time. Must not be NULL. Not written when the clock read fails.
Returns
RTE_STATUS_OK with *out_deadline written; RTE_STATUS_INVALID_PARAM for a NULL out_deadline; RTE_STATUS_INTERNAL_ERROR when clock_gettime(CLOCK_MONOTONIC) fails (the caller runs no callback/entry). REQ-OAL-TIMER-014

Definition at line 70 of file rte_posix_osadapter_period.c.

◆ posix_period_sleep_until()

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.

Loop, while *should_stop == 0:

  • reads CLOCK_MONOTONIC; returns when the deadline has passed (no wait);
  • takes the wake mutex, waiting at most the time left to the deadline (posix_osa_lock_bounded(), rounded up to whole milliseconds). A lock timeout is not an error: the clock is read again, so the deadline decides and an expiry is never early;
  • holding the mutex, reads *should_stop; if it is 0, waits on the wake condition variable - non-Apple hosts: pthread_cond_timedwait() to the absolute deadline on a CLOCK_MONOTONIC condition variable; macOS (no condition variable clock attribute): pthread_cond_timedwait_relative_np() of the time left, read again under the mutex;
  • reads *should_stop again and releases the mutex. A wake-up (0) or a timeout (ETIMEDOUT) without a stop goes round the loop: the clock is read again and the wait resumes to the same deadline.

A deadline already passed gives no wait. A stop request returns RTE_STATUS_OK before the deadline; the caller checks should_stop after every return.

Parameters
deadlineAbsolute CLOCK_MONOTONIC deadline (normalised). Must not be NULL.
should_stopThe thread's stop flag, read only. Must not be NULL.
Returns
RTE_STATUS_OK when the deadline is reached or a stop was requested; RTE_STATUS_INVALID_PARAM for a NULL argument; RTE_STATUS_INTERNAL_ERROR when the wake object does not exist, the clock cannot be read, the wake mutex returns an error other than a timeout, the wait returns an error other than ETIMEDOUT or the mutex cannot be released - the caller then stops its loop. REQ-OAL-TIMER-014

Definition at line 109 of file rte_posix_osadapter_period.c.

◆ posix_period_wake_all()

void posix_period_wake_all ( volatile sig_atomic_t * should_stop)

Requests a stop of a periodic thread and wakes it from its wait.

Stores 1 in *should_stop while it holds the wake mutex (bounded by RTE_POSIX_PERIOD_WAKE_LOCK_TIMEOUT_MS) and broadcasts on the wake condition variable, then releases the mutex. When the mutex cannot be taken in time (or the wake object does not exist) it stores 1 without the mutex and does not broadcast: the thread then ends at its next deadline. Not an error either way: there is no return value, and the caller still joins. Callable from any thread, including the periodic thread itself (its callback/entry runs outside the mutex). A NULL should_stop is ignored.

Parameters
should_stopThe thread's stop flag. Written (set to 1).
Returns
None.

Definition at line 139 of file rte_posix_osadapter_period.c.

◆ posix_period_wake_ready()

bool posix_period_wake_ready ( void )

Creates the process-wide wake object on the first call; true once it exists.

pthread_once(): a priority-inheritance mutex (PTHREAD_PRIO_INHERIT requested at run time on every host, as the mutex OSAdapter does) and a condition variable (non-Apple hosts: clock CLOCK_MONOTONIC). A refusal of any of these calls reports DEGRADED / RTE_SAFESTATE_REASON_OSA_RT_ATTRIBUTE once ("period wake object refused - timer/task create failed"), destroys what was created and makes this and every later call return false (not retried, same posture as the timer and task thread-specific-data key). Never deleted: it lives as long as the process.

Returns
true when the wake object exists; false when it was refused or pthread_once() failed.

Definition at line 127 of file rte_posix_osadapter_period.c.

◆ set_wake_clock()

bool set_wake_clock ( pthread_condattr_t * attr)
static

The condition variable's timed wait measures its absolute deadline on CLOCK_MONOTONIC, the clock of the deadline (the default would be CLOCK_REALTIME, which a wall-clock step moves).

Definition at line 221 of file rte_posix_osadapter_period.c.

◆ time_left_ns()

bool time_left_ns ( const struct timespec * deadline,
int64_t * out_ns )
static

Time left from now (CLOCK_MONOTONIC) to the deadline, in ns (<= 0 once it has passed). False when the clock cannot be read (*out_ns unwritten).

Definition at line 229 of file rte_posix_osadapter_period.c.

◆ wait_for_wake()

int wait_for_wake ( const struct timespec * deadline)
static

Absolute timed wait on the CLOCK_MONOTONIC condition variable (set_wake_clock()), to the same deadline as every earlier wait of this period. The error is the return value; errno is not used.

Definition at line 360 of file rte_posix_osadapter_period.c.

◆ wait_locked()

rte_status_t wait_locked ( const struct timespec * deadline,
const volatile sig_atomic_t * should_stop,
bool * out_waiting )
static

One wait step, called with the wake mutex held; releases it. *out_waiting: false once a stop was seen (read under the mutex) or the step failed. Returns RTE_STATUS_INTERNAL_ERROR when the wait returned an error other than ETIMEDOUT or the mutex could not be released.

Definition at line 303 of file rte_posix_osadapter_period.c.

◆ wait_to_deadline()

rte_status_t wait_to_deadline ( const struct timespec * deadline,
const volatile sig_atomic_t * should_stop )
static

The wait loop of posix_period_sleep_until() (see the header). The wake object exists.

Definition at line 258 of file rte_posix_osadapter_period.c.

Variable Documentation

◆ s_wake_cond

pthread_cond_t s_wake_cond
static

Definition at line 63 of file rte_posix_osadapter_period.c.

◆ s_wake_lock

pthread_mutex_t s_wake_lock
static

Local variables declarations

Definition at line 62 of file rte_posix_osadapter_period.c.

◆ s_wake_ready

bool s_wake_ready = false
static

Definition at line 64 of file rte_posix_osadapter_period.c.