5
5
* SPDX-License-Identifier: Apache-2.0
6
6
*/
7
7
8
+ #include "posix_clock.h"
8
9
#include "posix_internal.h"
9
10
11
+ #include <stdbool.h>
12
+
10
13
#include <zephyr/init.h>
11
14
#include <zephyr/kernel.h>
12
15
#include <zephyr/logging/log.h>
15
18
16
19
LOG_MODULE_REGISTER (pthread_cond , CONFIG_PTHREAD_COND_LOG_LEVEL );
17
20
18
- int64_t timespec_to_timeoutms (const struct timespec * abstime );
19
-
20
- __pinned_bss
21
- static struct k_condvar posix_cond_pool [CONFIG_MAX_PTHREAD_COND_COUNT ];
21
+ __pinned_bss static struct posix_cond posix_cond_pool [CONFIG_MAX_PTHREAD_COND_COUNT ];
22
22
23
23
SYS_BITARRAY_DEFINE_STATIC (posix_cond_bitarray , CONFIG_MAX_PTHREAD_COND_COUNT );
24
24
@@ -30,7 +30,7 @@ SYS_BITARRAY_DEFINE_STATIC(posix_cond_bitarray, CONFIG_MAX_PTHREAD_COND_COUNT);
30
30
BUILD_ASSERT (CONFIG_MAX_PTHREAD_COND_COUNT < PTHREAD_OBJ_MASK_INIT ,
31
31
"CONFIG_MAX_PTHREAD_COND_COUNT is too high" );
32
32
33
- static inline size_t posix_cond_to_offset (struct k_condvar * cv )
33
+ static inline size_t posix_cond_to_offset (struct posix_cond * cv )
34
34
{
35
35
return cv - posix_cond_pool ;
36
36
}
@@ -40,7 +40,7 @@ static inline size_t to_posix_cond_idx(pthread_cond_t cond)
40
40
return mark_pthread_obj_uninitialized (cond );
41
41
}
42
42
43
- static struct k_condvar * get_posix_cond (pthread_cond_t cond )
43
+ static struct posix_cond * get_posix_cond (pthread_cond_t cond )
44
44
{
45
45
int actually_initialized ;
46
46
size_t bit = to_posix_cond_idx (cond );
@@ -66,10 +66,30 @@ static struct k_condvar *get_posix_cond(pthread_cond_t cond)
66
66
return & posix_cond_pool [bit ];
67
67
}
68
68
69
- static struct k_condvar * to_posix_cond (pthread_cond_t * cvar )
69
+ static inline bool is_posix_condattr_valid (struct posix_condattr * attr )
70
+ {
71
+ if (attr == NULL ) {
72
+ return false;
73
+ }
74
+
75
+ if (!attr -> initialized ) {
76
+ LOG_DBG ("condattr is not initialized" );
77
+ return false;
78
+ }
79
+
80
+ /* revisit when POSIX_CLOCK_SELECTION is reworked */
81
+ if (!((attr -> clock == CLOCK_REALTIME ) || (attr -> clock == CLOCK_MONOTONIC ))) {
82
+ LOG_DBG ("condattr clock %u is invalid" , attr -> clock );
83
+ return false;
84
+ }
85
+
86
+ return true;
87
+ }
88
+
89
+ static struct posix_cond * to_posix_cond (pthread_cond_t * cvar )
70
90
{
71
91
size_t bit ;
72
- struct k_condvar * cv ;
92
+ struct posix_cond * cv ;
73
93
74
94
if (* cvar != PTHREAD_COND_INITIALIZER ) {
75
95
return get_posix_cond (* cvar );
@@ -85,24 +105,35 @@ static struct k_condvar *to_posix_cond(pthread_cond_t *cvar)
85
105
/* Record the associated posix_cond in mu and mark as initialized */
86
106
* cvar = mark_pthread_obj_initialized (bit );
87
107
cv = & posix_cond_pool [bit ];
108
+ (void )pthread_condattr_init ((pthread_condattr_t * )& cv -> attr );
88
109
89
110
return cv ;
90
111
}
91
112
92
- static int cond_wait (pthread_cond_t * cond , pthread_mutex_t * mu , k_timeout_t timeout )
113
+ static int cond_wait (pthread_cond_t * cond , pthread_mutex_t * mu , const struct timespec * abstime )
93
114
{
94
115
int ret ;
95
116
struct k_mutex * m ;
96
- struct k_condvar * cv ;
117
+ struct posix_cond * cv ;
118
+ k_timeout_t timeout = K_FOREVER ;
97
119
98
120
m = to_posix_mutex (mu );
99
121
cv = to_posix_cond (cond );
100
122
if (cv == NULL || m == NULL ) {
101
123
return EINVAL ;
102
124
}
103
125
126
+ if (abstime != NULL ) {
127
+ if (!is_timespec_valid (abstime )) {
128
+ LOG_DBG ("%s is invalid" , "abstime" );
129
+ return EINVAL ;
130
+ }
131
+
132
+ timeout = K_MSEC ((int32_t )timespec_to_timeoutms (cv -> attr .clock , abstime ));
133
+ }
134
+
104
135
LOG_DBG ("Waiting on cond %p with timeout %llx" , cv , timeout .ticks );
105
- ret = k_condvar_wait (cv , m , timeout );
136
+ ret = k_condvar_wait (& cv -> condvar , m , timeout );
106
137
if (ret == - EAGAIN ) {
107
138
LOG_DBG ("Timeout waiting on cond %p" , cv );
108
139
ret = ETIMEDOUT ;
@@ -120,15 +151,15 @@ static int cond_wait(pthread_cond_t *cond, pthread_mutex_t *mu, k_timeout_t time
120
151
int pthread_cond_signal (pthread_cond_t * cvar )
121
152
{
122
153
int ret ;
123
- struct k_condvar * cv ;
154
+ struct posix_cond * cv ;
124
155
125
156
cv = to_posix_cond (cvar );
126
157
if (cv == NULL ) {
127
158
return EINVAL ;
128
159
}
129
160
130
161
LOG_DBG ("Signaling cond %p" , cv );
131
- ret = k_condvar_signal (cv );
162
+ ret = k_condvar_signal (& cv -> condvar );
132
163
if (ret < 0 ) {
133
164
LOG_DBG ("k_condvar_signal() failed: %d" , ret );
134
165
return - ret ;
@@ -142,15 +173,15 @@ int pthread_cond_signal(pthread_cond_t *cvar)
142
173
int pthread_cond_broadcast (pthread_cond_t * cvar )
143
174
{
144
175
int ret ;
145
- struct k_condvar * cv ;
176
+ struct posix_cond * cv ;
146
177
147
178
cv = get_posix_cond (* cvar );
148
179
if (cv == NULL ) {
149
180
return EINVAL ;
150
181
}
151
182
152
183
LOG_DBG ("Broadcasting on cond %p" , cv );
153
- ret = k_condvar_broadcast (cv );
184
+ ret = k_condvar_broadcast (& cv -> condvar );
154
185
if (ret < 0 ) {
155
186
LOG_DBG ("k_condvar_broadcast() failed: %d" , ret );
156
187
return - ret ;
@@ -163,27 +194,33 @@ int pthread_cond_broadcast(pthread_cond_t *cvar)
163
194
164
195
int pthread_cond_wait (pthread_cond_t * cv , pthread_mutex_t * mut )
165
196
{
166
- return cond_wait (cv , mut , K_FOREVER );
197
+ return cond_wait (cv , mut , NULL );
167
198
}
168
199
169
200
int pthread_cond_timedwait (pthread_cond_t * cv , pthread_mutex_t * mut , const struct timespec * abstime )
170
201
{
171
- return cond_wait (cv , mut , K_MSEC (( int32_t ) timespec_to_timeoutms ( abstime )) );
202
+ return cond_wait (cv , mut , abstime );
172
203
}
173
204
174
205
int pthread_cond_init (pthread_cond_t * cvar , const pthread_condattr_t * att )
175
206
{
176
- struct k_condvar * cv ;
207
+ struct posix_cond * cv ;
177
208
178
- ARG_UNUSED (att );
179
209
* cvar = PTHREAD_COND_INITIALIZER ;
180
-
181
- /* calls k_condvar_init() */
182
210
cv = to_posix_cond (cvar );
183
211
if (cv == NULL ) {
184
212
return ENOMEM ;
185
213
}
186
214
215
+ if (att != NULL ) {
216
+ if (!is_posix_condattr_valid ((struct posix_condattr * )att )) {
217
+ LOG_ERR ("%s invalid" , "pthread_condattr_t" );
218
+ return EINVAL ;
219
+ }
220
+
221
+ cv -> attr = * ((const struct posix_condattr * )att );
222
+ }
223
+
187
224
LOG_DBG ("Initialized cond %p" , cv );
188
225
189
226
return 0 ;
@@ -193,7 +230,7 @@ int pthread_cond_destroy(pthread_cond_t *cvar)
193
230
{
194
231
int err ;
195
232
size_t bit ;
196
- struct k_condvar * cv ;
233
+ struct posix_cond * cv ;
197
234
198
235
cv = get_posix_cond (* cvar );
199
236
if (cv == NULL ) {
@@ -218,7 +255,7 @@ static int pthread_cond_pool_init(void)
218
255
size_t i ;
219
256
220
257
for (i = 0 ; i < CONFIG_MAX_PTHREAD_COND_COUNT ; ++ i ) {
221
- err = k_condvar_init (& posix_cond_pool [i ]);
258
+ err = k_condvar_init (& posix_cond_pool [i ]. condvar );
222
259
__ASSERT_NO_MSG (err == 0 );
223
260
}
224
261
@@ -229,33 +266,56 @@ int pthread_condattr_init(pthread_condattr_t *att)
229
266
{
230
267
__ASSERT_NO_MSG (att != NULL );
231
268
232
- att -> clock = CLOCK_MONOTONIC ;
269
+ struct posix_condattr * const attr = (struct posix_condattr * )att ;
270
+
271
+ attr -> clock = CLOCK_REALTIME ;
272
+ attr -> initialized = true;
233
273
234
274
return 0 ;
235
275
}
236
276
237
277
int pthread_condattr_destroy (pthread_condattr_t * att )
238
278
{
239
- ARG_UNUSED (att );
279
+ struct posix_condattr * const attr = (struct posix_condattr * )att ;
280
+
281
+ if (attr == NULL ) {
282
+ return EINVAL ;
283
+ }
284
+
285
+ * attr = (struct posix_condattr ){0 };
240
286
241
287
return 0 ;
242
288
}
243
289
244
290
int pthread_condattr_getclock (const pthread_condattr_t * ZRESTRICT att ,
245
291
clockid_t * ZRESTRICT clock_id )
246
292
{
247
- * clock_id = att -> clock ;
293
+ struct posix_condattr * const attr = (struct posix_condattr * )att ;
294
+
295
+ if ((attr == NULL ) || !attr -> initialized ) {
296
+ LOG_DBG ("condattr is not initialized" );
297
+ return EINVAL ;
298
+ }
299
+
300
+ * clock_id = attr -> clock ;
248
301
249
302
return 0 ;
250
303
}
251
304
252
305
int pthread_condattr_setclock (pthread_condattr_t * att , clockid_t clock_id )
253
306
{
307
+ struct posix_condattr * const attr = (struct posix_condattr * )att ;
308
+
254
309
if (clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC ) {
255
310
return - EINVAL ;
256
311
}
257
312
258
- att -> clock = clock_id ;
313
+ if ((attr == NULL ) || !attr -> initialized ) {
314
+ LOG_DBG ("condattr is not initialized" );
315
+ return EINVAL ;
316
+ }
317
+
318
+ attr -> clock = clock_id ;
259
319
260
320
return 0 ;
261
321
}
0 commit comments