1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_POSIX_PTHREAD_H_
8 #define ZEPHYR_INCLUDE_POSIX_PTHREAD_H_
9 
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include <zephyr/kernel.h>
14 #include <zephyr/posix/time.h>
15 #include <zephyr/posix/unistd.h>
16 #include <zephyr/posix/sched.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 /*
23  * Pthread detach/joinable
24  * Undefine possibly predefined values by external toolchain headers
25  */
26 #undef PTHREAD_CREATE_DETACHED
27 #define PTHREAD_CREATE_DETACHED 1
28 #undef PTHREAD_CREATE_JOINABLE
29 #define PTHREAD_CREATE_JOINABLE 0
30 
31 /* Pthread resource visibility */
32 #define PTHREAD_PROCESS_PRIVATE 0
33 #define PTHREAD_PROCESS_SHARED  1
34 
35 /* Pthread cancellation */
36 #define PTHREAD_CANCELED       ((void *)-1)
37 #define PTHREAD_CANCEL_ENABLE  0
38 #define PTHREAD_CANCEL_DISABLE 1
39 #define PTHREAD_CANCEL_DEFERRED     0
40 #define PTHREAD_CANCEL_ASYNCHRONOUS 1
41 
42 /* Pthread scope */
43 #undef PTHREAD_SCOPE_PROCESS
44 #define PTHREAD_SCOPE_PROCESS    1
45 #undef PTHREAD_SCOPE_SYSTEM
46 #define PTHREAD_SCOPE_SYSTEM     0
47 
48 /* Pthread inherit scheduler */
49 #undef PTHREAD_INHERIT_SCHED
50 #define PTHREAD_INHERIT_SCHED  0
51 #undef PTHREAD_EXPLICIT_SCHED
52 #define PTHREAD_EXPLICIT_SCHED 1
53 
54 /* Passed to pthread_once */
55 #define PTHREAD_ONCE_INIT {0}
56 
57 /* The minimum allowable stack size */
58 #define PTHREAD_STACK_MIN K_KERNEL_STACK_LEN(0)
59 
60 /**
61  * @brief Declare a condition variable as initialized
62  *
63  * Initialize a condition variable with the default condition variable attributes.
64  */
65 #define PTHREAD_COND_INITIALIZER (-1)
66 
67 /**
68  * @brief POSIX threading compatibility API
69  *
70  * See IEEE 1003.1
71  */
72 int pthread_cond_init(pthread_cond_t *cv, const pthread_condattr_t *att);
73 
74 /**
75  * @brief POSIX threading compatibility API
76  *
77  * See IEEE 1003.1
78  */
79 int pthread_cond_destroy(pthread_cond_t *cv);
80 
81 /**
82  * @brief POSIX threading compatibility API
83  *
84  * See IEEE 1003.1
85  */
86 int pthread_cond_signal(pthread_cond_t *cv);
87 
88 /**
89  * @brief POSIX threading compatibility API
90  *
91  * See IEEE 1003.1
92  */
93 int pthread_cond_broadcast(pthread_cond_t *cv);
94 
95 /**
96  * @brief POSIX threading compatibility API
97  *
98  * See IEEE 1003.1
99  */
100 int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mut);
101 
102 /**
103  * @brief POSIX threading compatibility API
104  *
105  * See IEEE 1003.1
106  */
107 int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mut,
108 			   const struct timespec *abstime);
109 
110 /**
111  * @brief POSIX threading compatibility API
112  *
113  * See IEEE 1003.1.
114  *
115  */
116 int pthread_condattr_init(pthread_condattr_t *att);
117 
118 /**
119  * @brief POSIX threading compatibility API
120  *
121  * See IEEE 1003.1
122  *
123  */
124 int pthread_condattr_destroy(pthread_condattr_t *att);
125 
126 /**
127  * @brief POSIX threading compatibility API
128  *
129  * See IEEE 1003.1
130  *
131  */
132 int pthread_condattr_getclock(const pthread_condattr_t *ZRESTRICT att,
133 		clockid_t *ZRESTRICT clock_id);
134 
135 /**
136  * @brief POSIX threading compatibility API
137  *
138  * See IEEE 1003.1
139  *
140  */
141 
142 int pthread_condattr_setclock(pthread_condattr_t *att, clockid_t clock_id);
143 
144 /**
145  * @brief Declare a mutex as initialized
146  *
147  * Initialize a mutex with the default mutex attributes.
148  */
149 #define PTHREAD_MUTEX_INITIALIZER (-1)
150 
151 /**
152  * @brief Declare a rwlock as initialized
153  *
154  * Initialize a rwlock with the default rwlock attributes.
155  */
156 #define PTHREAD_RWLOCK_INITIALIZER (-1)
157 
158 /*
159  *  Mutex attributes - type
160  *
161  *  PTHREAD_MUTEX_NORMAL: Owner of mutex cannot relock it. Attempting
162  *      to relock will cause deadlock.
163  *  PTHREAD_MUTEX_RECURSIVE: Owner can relock the mutex.
164  *  PTHREAD_MUTEX_ERRORCHECK: If owner attempts to relock the mutex, an
165  *      error is returned.
166  *
167  */
168 #define PTHREAD_MUTEX_NORMAL        0
169 #define PTHREAD_MUTEX_RECURSIVE     1
170 #define PTHREAD_MUTEX_ERRORCHECK    2
171 #define PTHREAD_MUTEX_DEFAULT       PTHREAD_MUTEX_NORMAL
172 
173 /*
174  *  Mutex attributes - protocol
175  *
176  *  PTHREAD_PRIO_NONE: Ownership of mutex does not affect priority.
177  *  PTHREAD_PRIO_INHERIT: Owner's priority is boosted to the priority of
178  *      highest priority thread blocked on the mutex.
179  *  PTHREAD_PRIO_PROTECT:  Mutex has a priority ceiling.  The owner's
180  *      priority is boosted to the highest priority ceiling of all mutexes
181  *      owned (regardless of whether or not other threads are blocked on
182  *      any of these mutexes).
183  *  FIXME: Only PRIO_NONE is supported. Implement other protocols.
184  */
185 #define PTHREAD_PRIO_NONE           0
186 
187 /**
188  * @brief POSIX threading compatibility API
189  *
190  * See IEEE 1003.1
191  */
192 int pthread_mutex_destroy(pthread_mutex_t *m);
193 
194 /**
195  * @brief POSIX threading compatibility API
196  *
197  * See IEEE 1003.1
198  */
199 int pthread_mutex_lock(pthread_mutex_t *m);
200 
201 /**
202  * @brief POSIX threading compatibility API
203  *
204  * See IEEE 1003.1
205  */
206 int pthread_mutex_unlock(pthread_mutex_t *m);
207 
208 /**
209  * @brief POSIX threading compatibility API
210  *
211  * See IEEE 1003.1
212  */
213 
214 int pthread_mutex_timedlock(pthread_mutex_t *m,
215 			    const struct timespec *abstime);
216 
217 /**
218  * @brief POSIX threading compatibility API
219  *
220  * See IEEE 1003.1
221  */
222 int pthread_mutex_trylock(pthread_mutex_t *m);
223 
224 /**
225  * @brief POSIX threading compatibility API
226  *
227  * See IEEE 1003.1
228  */
229 int pthread_mutex_init(pthread_mutex_t *m,
230 				     const pthread_mutexattr_t *att);
231 
232 /**
233  * @brief POSIX threading compatibility API
234  *
235  * See IEEE 1003.1
236  */
237 int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol);
238 
239 /**
240  * @brief POSIX threading compatibility API
241  *
242  * See IEEE 1003.1
243  */
244 int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
245 
246 /**
247  * @brief POSIX threading compatibility API
248  *
249  * See IEEE 1003.1
250  */
251 int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr,
252 				  int *protocol);
253 
254 /**
255  * @brief POSIX threading compatibility API
256  *
257  * See IEEE 1003.1
258  */
259 int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
260 
261 /**
262  * @brief POSIX threading compatibility API
263  *
264  * See IEEE 1003.1
265  *
266  * Note that pthread attribute structs are currently noops in Zephyr.
267  */
268 int pthread_mutexattr_init(pthread_mutexattr_t *attr);
269 
270 /**
271  * @brief POSIX threading compatibility API
272  *
273  * See IEEE 1003.1
274  *
275  * Note that pthread attribute structs are currently noops in Zephyr.
276  */
277 int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
278 
279 #define PTHREAD_BARRIER_SERIAL_THREAD 1
280 
281 /*
282  *  Barrier attributes - type
283  */
284 #define PTHREAD_PROCESS_PRIVATE		0
285 #define PTHREAD_PROCESS_PUBLIC		1
286 
287 /**
288  * @brief POSIX threading compatibility API
289  *
290  * See IEEE 1003.1
291  */
292 int pthread_barrier_wait(pthread_barrier_t *b);
293 
294 /**
295  * @brief POSIX threading compatibility API
296  *
297  * See IEEE 1003.1
298  */
299 int pthread_barrier_init(pthread_barrier_t *b, const pthread_barrierattr_t *attr,
300 			 unsigned int count);
301 
302 /**
303  * @brief POSIX threading compatibility API
304  *
305  * See IEEE 1003.1
306  */
307 int pthread_barrier_destroy(pthread_barrier_t *b);
308 
309 /**
310  * @brief POSIX threading compatibility API
311  *
312  * See IEEE 1003.1
313  */
314 int pthread_barrierattr_init(pthread_barrierattr_t *b);
315 
316 /**
317  * @brief POSIX threading compatibility API
318  *
319  * See IEEE 1003.1
320  */
321 int pthread_barrierattr_destroy(pthread_barrierattr_t *b);
322 
323 /**
324  * @brief POSIX threading compatibility API
325  *
326  * See IEEE 1003.1
327  */
328 int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared);
329 
330 /**
331  * @brief POSIX threading compatibility API
332  *
333  * See IEEE 1003.1
334  */
335 int pthread_barrierattr_getpshared(const pthread_barrierattr_t *ZRESTRICT attr,
336 				   int *ZRESTRICT pshared);
337 
338 /* Predicates and setters for various pthread attribute values that we
339  * don't support (or always support: the "process shared" attribute
340  * can only be true given the way Zephyr implements these
341  * objects). Leave these undefined for simplicity instead of defining
342  * stubs to return an error that would have to be logged and
343  * interpreted just to figure out that we didn't support it in the
344  * first place. These APIs are very rarely used even in production
345  * Unix code.  Leave the declarations here so they can be easily
346  * uncommented and implemented as needed.
347 
348 int pthread_condattr_getpshared(const pthread_condattr_t * int *);
349 int pthread_condattr_setpshared(pthread_condattr_t *, int);
350 int pthread_mutex_consistent(pthread_mutex_t *);
351 int pthread_mutex_getprioceiling(const pthread_mutex_t * int *);
352 int pthread_mutex_setprioceiling(pthread_mutex_t *, int int *);
353 int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *, int *);
354 int pthread_mutexattr_getpshared(const pthread_mutexattr_t * int *);
355 int pthread_mutexattr_getrobust(const pthread_mutexattr_t * int *);
356 int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);
357 int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
358 int pthread_mutexattr_setrobust(pthread_mutexattr_t *, int);
359 */
360 
361 /* Base Pthread related APIs */
362 
363 /**
364  * @brief Obtain ID of the calling thread.
365  *
366  * The results of calling this API from threads not created with
367  * pthread_create() are undefined.
368  *
369  * See IEEE 1003.1
370  */
371 pthread_t pthread_self(void);
372 
373 /**
374  * @brief Compare thread IDs.
375  *
376  * See IEEE 1003.1
377  */
378 int pthread_equal(pthread_t pt1, pthread_t pt2);
379 
380 /**
381  * @brief Destroy the read-write lock attributes object.
382  *
383  * See IEEE 1003.1
384  */
385 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
386 
387 /**
388  * @brief initialize the read-write lock attributes object.
389  *
390  * See IEEE 1003.1
391  */
392 int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
393 
394 int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *ZRESTRICT attr,
395 				  int *ZRESTRICT pshared);
396 int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
397 
398 int pthread_attr_getguardsize(const pthread_attr_t *ZRESTRICT attr, size_t *ZRESTRICT guardsize);
399 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
400 int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
401 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
402 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
403 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
404 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
405 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
406 int pthread_attr_init(pthread_attr_t *attr);
407 int pthread_attr_destroy(pthread_attr_t *attr);
408 int pthread_attr_getschedparam(const pthread_attr_t *attr,
409 			       struct sched_param *schedparam);
410 int pthread_getschedparam(pthread_t pthread, int *policy,
411 			  struct sched_param *param);
412 int pthread_attr_getstack(const pthread_attr_t *attr,
413 			  void **stackaddr, size_t *stacksize);
414 int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,
415 			  size_t stacksize);
416 int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope);
417 int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);
418 int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched);
419 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
420 #ifdef CONFIG_POSIX_THREADS
421 int pthread_once(pthread_once_t *once, void (*initFunc)(void));
422 #endif
423 FUNC_NORETURN void pthread_exit(void *retval);
424 int pthread_join(pthread_t thread, void **status);
425 int pthread_cancel(pthread_t pthread);
426 int pthread_detach(pthread_t thread);
427 int pthread_create(pthread_t *newthread, const pthread_attr_t *attr,
428 		   void *(*threadroutine)(void *), void *arg);
429 int pthread_setcancelstate(int state, int *oldstate);
430 int pthread_setcanceltype(int type, int *oldtype);
431 void pthread_testcancel(void);
432 int pthread_attr_setschedparam(pthread_attr_t *attr,
433 			       const struct sched_param *schedparam);
434 int pthread_setschedparam(pthread_t pthread, int policy,
435 			  const struct sched_param *param);
436 int pthread_setschedprio(pthread_t thread, int prio);
437 int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
438 int pthread_rwlock_init(pthread_rwlock_t *rwlock,
439 			const pthread_rwlockattr_t *attr);
440 int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
441 int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock,
442 			       const struct timespec *abstime);
443 int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock,
444 			       const struct timespec *abstime);
445 int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
446 int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
447 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
448 int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
449 int pthread_key_create(pthread_key_t *key,
450 		void (*destructor)(void *));
451 int pthread_key_delete(pthread_key_t key);
452 int pthread_setspecific(pthread_key_t key, const void *value);
453 void *pthread_getspecific(pthread_key_t key);
454 int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
455 int pthread_getconcurrency(void);
456 int pthread_setconcurrency(int new_level);
457 
458 void __z_pthread_cleanup_push(void *cleanup[3], void (*routine)(void *arg), void *arg);
459 void __z_pthread_cleanup_pop(int execute);
460 
461 #define pthread_cleanup_push(_rtn, _arg)                                                           \
462 	do /* enforce '{'-like behaviour */ {                                                      \
463 		void *_z_pthread_cleanup[3];                                                       \
464 		__z_pthread_cleanup_push(_z_pthread_cleanup, _rtn, _arg)
465 
466 #define pthread_cleanup_pop(_ex)                                                                   \
467 		__z_pthread_cleanup_pop(_ex);                                                      \
468 	} /* enforce '}'-like behaviour */ while (0)
469 
470 /* Glibc / Oracle Extension Functions */
471 
472 /**
473  * @brief Set name of POSIX thread.
474  *
475  * Non-portable, extension function that conforms with most
476  * other definitions of this function.
477  *
478  * @param thread POSIX thread to set name
479  * @param name Name string
480  * @retval 0 Success
481  * @retval ESRCH Thread does not exist
482  * @retval EINVAL Name buffer is NULL
483  * @retval Negative value if kernel function error
484  *
485  */
486 int pthread_setname_np(pthread_t thread, const char *name);
487 
488 /**
489  * @brief Get name of POSIX thread and store in name buffer
490  *  	  that is of size len.
491  *
492  * Non-portable, extension function that conforms with most
493  * other definitions of this function.
494  *
495  * @param thread POSIX thread to obtain name information
496  * @param name Destination buffer
497  * @param len Destination buffer size
498  * @retval 0 Success
499  * @retval ESRCH Thread does not exist
500  * @retval EINVAL Name buffer is NULL
501  * @retval Negative value if kernel function error
502  */
503 int pthread_getname_np(pthread_t thread, char *name, size_t len);
504 
505 #ifdef CONFIG_POSIX_THREADS
506 
507 /**
508  * @brief Destroy a pthread_spinlock_t.
509  *
510  * See IEEE 1003.1
511  */
512 int pthread_spin_destroy(pthread_spinlock_t *lock);
513 
514 /**
515  * @brief Initialize a thread_spinlock_t.
516  *
517  * See IEEE 1003.1
518  */
519 int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
520 
521 /**
522  * @brief Lock a previously initialized thread_spinlock_t.
523  *
524  * See IEEE 1003.1
525  */
526 int pthread_spin_lock(pthread_spinlock_t *lock);
527 
528 /**
529  * @brief Attempt to lock a previously initialized thread_spinlock_t.
530  *
531  * See IEEE 1003.1
532  */
533 int pthread_spin_trylock(pthread_spinlock_t *lock);
534 
535 /**
536  * @brief Unlock a previously locked thread_spinlock_t.
537  *
538  * See IEEE 1003.1
539  */
540 int pthread_spin_unlock(pthread_spinlock_t *lock);
541 
542 #endif
543 
544 #ifdef __cplusplus
545 }
546 #endif
547 
548 #endif /* ZEPHYR_INCLUDE_POSIX_PTHREAD_H_ */
549