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