1 /*
2  * Copyright (c) 2022 Meta
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_LIB_POSIX_POSIX_INTERNAL_H_
8 #define ZEPHYR_LIB_POSIX_POSIX_INTERNAL_H_
9 
10 #include <stdbool.h>
11 #include <stdint.h>
12 
13 #include <zephyr/kernel.h>
14 #include <zephyr/posix/pthread.h>
15 #include <zephyr/posix/signal.h>
16 #include <zephyr/sys/dlist.h>
17 #include <zephyr/sys/slist.h>
18 
19 /*
20  * Bit used to mark a pthread object as initialized. Initialization status is
21  * verified (against internal status) in lock / unlock / destroy functions.
22  */
23 #define PTHREAD_OBJ_MASK_INIT 0x80000000
24 
25 struct posix_thread_attr {
26 	void *stack;
27 	/* the following two bitfields should combine to be 32-bits in size */
28 	uint32_t stacksize : CONFIG_POSIX_PTHREAD_ATTR_STACKSIZE_BITS;
29 	uint16_t guardsize : CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_BITS;
30 	int8_t priority;
31 	uint8_t schedpolicy: 2;
32 	union {
33 		bool caller_destroys: 1;
34 		bool initialized: 1;
35 	};
36 	bool cancelpending: 1;
37 	bool cancelstate: 1;
38 	bool canceltype: 1;
39 	bool detachstate: 1;
40 };
41 
42 struct posix_thread {
43 	struct k_thread thread;
44 
45 	/* List nodes for pthread_cleanup_push() / pthread_cleanup_pop() */
46 	sys_slist_t cleanup_list;
47 
48 	/* List node for ready_q, run_q, or done_q */
49 	sys_dnode_t q_node;
50 
51 	/* List of keys that thread has called pthread_setspecific() on */
52 	sys_slist_t key_list;
53 
54 	/* pthread_attr_t */
55 	struct posix_thread_attr attr;
56 
57 	/* Exit status */
58 	void *retval;
59 
60 	/* Signal mask */
61 	sigset_t sigset;
62 
63 	/* Queue ID (internal-only) */
64 	uint8_t qid;
65 };
66 
67 typedef struct pthread_key_obj {
68 	/* List of pthread_key_data objects that contain thread
69 	 * specific data for the key
70 	 */
71 	sys_slist_t key_data_l;
72 
73 	/* Optional destructor that is passed to pthread_key_create() */
74 	void (*destructor)(void *value);
75 } pthread_key_obj;
76 
77 typedef struct pthread_thread_data {
78 	sys_snode_t node;
79 
80 	/* Key and thread specific data passed to pthread_setspecific() */
81 	pthread_key_obj *key;
82 	void *spec_data;
83 } pthread_thread_data;
84 
is_pthread_obj_initialized(uint32_t obj)85 static inline bool is_pthread_obj_initialized(uint32_t obj)
86 {
87 	return (obj & PTHREAD_OBJ_MASK_INIT) != 0;
88 }
89 
mark_pthread_obj_initialized(uint32_t obj)90 static inline uint32_t mark_pthread_obj_initialized(uint32_t obj)
91 {
92 	return obj | PTHREAD_OBJ_MASK_INIT;
93 }
94 
mark_pthread_obj_uninitialized(uint32_t obj)95 static inline uint32_t mark_pthread_obj_uninitialized(uint32_t obj)
96 {
97 	return obj & ~PTHREAD_OBJ_MASK_INIT;
98 }
99 
100 struct posix_thread *to_posix_thread(pthread_t pth);
101 
102 /* get and possibly initialize a posix_mutex */
103 struct k_mutex *to_posix_mutex(pthread_mutex_t *mu);
104 
105 int posix_to_zephyr_priority(int priority, int policy);
106 int zephyr_to_posix_priority(int priority, int *policy);
107 
108 #endif
109