SafeAPI Backend POSIX
POSIX/Linux OAL backend for safeAPIFreamwork
Loading...
Searching...
No Matches
sapi_posix_backend_mutex.c
Go to the documentation of this file.
1
10
11#include <pthread.h>
12#include "safeapi/oal/memory/sapi_mem_util.h"
13
15
17typedef struct
18{
19 pthread_mutex_t mutex;
20 sapi_mutex_handle_t self_handle;
22
23/* C99-compatible static assert: posix_mutex_state_t must fit inside
24 * sapi_mutex_storage_t's reserved bytes (a negative array size is a
25 * compile error) - same convention as sapi_posix_backend_timer.c's own. */
26typedef char posix_mutex_storage_fits_[(sizeof(posix_mutex_state_t) <= sizeof(sapi_mutex_storage_t)) ? 1 : -1];
27
29static sapi_status_t backend_create(sapi_mutex_storage_t *storage, sapi_mutex_handle_t *out_handle);
30static sapi_status_t backend_lock(sapi_mutex_handle_t handle);
31static sapi_status_t backend_unlock(sapi_mutex_handle_t handle);
32static sapi_status_t backend_destroy(sapi_mutex_handle_t handle);
33
35static const sapi_mutex_backend_t s_posix_mutex_backend = { backend_create, backend_lock, backend_unlock,
36 backend_destroy };
37
39
40
42const sapi_mutex_backend_t *sapi_posix_backend_mutex(void)
43{
45}
46
47
48/****Local functions ****/
49
50static sapi_status_t backend_create(sapi_mutex_storage_t *storage, sapi_mutex_handle_t *out_handle)
51{
53 pthread_mutexattr_t attr;
54 int attr_init_ok = 0;
55 int init_rc;
56
57 if ((storage == NULL) || (out_handle == NULL))
58 {
59 return SAPI_STATUS_INVALID_PARAM;
60 }
61
62 state = (posix_mutex_state_t *)(void *)storage;
63 sapi_mem_set(state, 0, sizeof(*state));
64
65 /* Initialize attributes and try enabling Priority Inheritance (PTHREAD_PRIO_INHERIT)
66 * to prevent priority inversion under RT Linux / PREEMPT_RT. */
67 if (pthread_mutexattr_init(&attr) == 0)
68 {
69 attr_init_ok = 1;
70#if defined(_POSIX_THREAD_PRIO_INHERIT) && (_POSIX_THREAD_PRIO_INHERIT > 0)
71 (void)pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
72#endif
73 }
74
75 init_rc = pthread_mutex_init(&state->mutex, (attr_init_ok != 0) ? &attr : NULL);
76 if ((init_rc != 0) && (attr_init_ok != 0))
77 {
78 /* Fallback without priority inheritance if the platform/kernel rejects it */
79 init_rc = pthread_mutex_init(&state->mutex, NULL);
80 }
81
82 if (attr_init_ok != 0)
83 {
84 (void)pthread_mutexattr_destroy(&attr);
85 }
86
87 if (init_rc != 0)
88 {
89 return SAPI_STATUS_INTERNAL_ERROR;
90 }
91
92 state->self_handle = (sapi_mutex_handle_t)(void *)storage;
93 *out_handle = state->self_handle;
94 return SAPI_STATUS_OK;
95}
96
97static sapi_status_t backend_lock(sapi_mutex_handle_t handle)
98{
99 posix_mutex_state_t *state = (posix_mutex_state_t *)(void *)handle;
100
101 if (state == NULL)
102 {
103 return SAPI_STATUS_INVALID_PARAM;
104 }
105 if (pthread_mutex_lock(&state->mutex) != 0)
106 {
107 return SAPI_STATUS_INTERNAL_ERROR;
108 }
109 return SAPI_STATUS_OK;
110}
111
112static sapi_status_t backend_unlock(sapi_mutex_handle_t handle)
113{
114 posix_mutex_state_t *state = (posix_mutex_state_t *)(void *)handle;
115
116 if (state == NULL)
117 {
118 return SAPI_STATUS_INVALID_PARAM;
119 }
120 if (pthread_mutex_unlock(&state->mutex) != 0)
121 {
122 return SAPI_STATUS_INTERNAL_ERROR;
123 }
124 return SAPI_STATUS_OK;
125}
126
127static sapi_status_t backend_destroy(sapi_mutex_handle_t handle)
128{
129 posix_mutex_state_t *state = (posix_mutex_state_t *)(void *)handle;
130
131 if (state == NULL)
132 {
133 return SAPI_STATUS_INVALID_PARAM;
134 }
135 if (pthread_mutex_destroy(&state->mutex) != 0)
136 {
137 return SAPI_STATUS_INTERNAL_ERROR;
138 }
139 return SAPI_STATUS_OK;
140}
Real POSIX/Linux backend for every OAL service (ADR-018).
const sapi_mutex_backend_t * sapi_posix_backend_mutex(void)
The POSIX sapi_mutex backend (a thin pthread_mutex_t wrapper, ADR-033).
static const sapi_mutex_backend_t s_posix_mutex_backend