37#include <sys/resource.h>
43#include "safeapi/oal/memory/sapi_mem_util.h"
44#include "safeapi/oal/log/sapi_log.h"
51#define POSIX_PLATFORM_STACK_PREFAULT_BYTES (128U * 1024U)
53#define POSIX_PLATFORM_PAGE_BYTES 4096U
61static void posix_platform_lock_memory(
void);
62static void posix_platform_prefault_stack(
void);
63static void posix_platform_set_rt_priority(uint32_t rt_priority);
86 posix_platform_lock_memory();
87 posix_platform_prefault_stack();
90 posix_platform_set_rt_priority(rt_priority);
95 return SAPI_STATUS_OK;
99static void posix_platform_lock_memory(
void)
101 struct rlimit memlock_limit;
102 int lock_flags = MCL_CURRENT | MCL_FUTURE;
105 if ((getrlimit(RLIMIT_MEMLOCK, &memlock_limit) == 0) && (memlock_limit.rlim_cur != RLIM_INFINITY))
110 lock_flags = MCL_CURRENT;
111 (void)snprintf(msg,
sizeof(msg),
112 "RLIMIT_MEMLOCK bounded at %lu KiB - locking current memory only "
113 "(MCL_FUTURE would break later thread creation)",
114 (
unsigned long)(memlock_limit.rlim_cur / 1024UL));
115 sapi_log_write(SAPI_LOG_LEVEL_WARNING,
"RT-LINUX", msg);
118 if (mlockall(lock_flags) != 0)
120 (void)snprintf(msg,
sizeof(msg),
"mlockall(0x%x) skipped or not permitted (errno=%d: %s)",
121 (
unsigned int)lock_flags, errno, strerror(errno));
122 sapi_log_write(SAPI_LOG_LEVEL_WARNING,
"RT-LINUX", msg);
124 else if (lock_flags == MCL_CURRENT)
126 sapi_log_write(SAPI_LOG_LEVEL_INFO,
"RT-LINUX",
"mlockall(MCL_CURRENT) enabled: current memory locked into RAM");
130 sapi_log_write(SAPI_LOG_LEVEL_INFO,
"RT-LINUX",
131 "mlockall(MCL_CURRENT|MCL_FUTURE) enabled: memory locked into RAM");
135static void posix_platform_prefault_stack(
void)
137 volatile uint8_t dummy_stack[POSIX_PLATFORM_STACK_PREFAULT_BYTES];
140 for (page_idx = 0U; page_idx <
sizeof(dummy_stack); page_idx += POSIX_PLATFORM_PAGE_BYTES)
142 dummy_stack[page_idx] = 0U;
146static void posix_platform_set_rt_priority(uint32_t rt_priority)
148 struct sched_param sched;
149 int min_prio = sched_get_priority_min(SCHED_FIFO);
150 int max_prio = sched_get_priority_max(SCHED_FIFO);
151 int wanted = (int)rt_priority;
154 if ((min_prio < 0) || (max_prio < 0))
158 if (wanted < min_prio)
162 if (wanted > max_prio)
167 sapi_mem_set(&sched, 0,
sizeof(sched));
168 sched.sched_priority = wanted;
170 if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched) == 0)
172 (void)snprintf(msg,
sizeof(msg),
"SCHED_FIFO priority successfully set to %d", wanted);
173 sapi_log_write(SAPI_LOG_LEVEL_INFO,
"RT-LINUX", msg);
177 (void)snprintf(msg,
sizeof(msg),
"pthread_setschedparam(SCHED_FIFO, prio=%d) skipped or unprivileged (errno=%d: %s)",
178 wanted, errno, strerror(errno));
179 sapi_log_write(SAPI_LOG_LEVEL_WARNING,
"RT-LINUX", msg);
Real POSIX/Linux backend for every OAL service (ADR-018).
const sapi_platform_backend_t * sapi_posix_backend_platform(void)
The POSIX sapi_platform backend (ADR-035): real-time bring-up via mlockall() + SCHED_FIFO,...