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 #ifdef CONFIG_RX
26 struct __packed posix_thread_attr
27 #else
28 struct posix_thread_attr
29 #endif
30 {
31 	void *stack;
32 	/* the following two bitfields should combine to be 32-bits in size */
33 	uint32_t stacksize: CONFIG_POSIX_PTHREAD_ATTR_STACKSIZE_BITS;
34 	uint16_t guardsize: CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_BITS;
35 	int8_t priority;
36 	uint8_t schedpolicy: 2;
37 	bool contentionscope: 1;
38 	bool inheritsched: 1;
39 	union {
40 		bool caller_destroys: 1;
41 		bool initialized: 1;
42 	};
43 	bool cancelpending: 1;
44 	bool cancelstate: 1;
45 	bool canceltype: 1;
46 	bool detachstate: 1;
47 };
48 
49 struct posix_thread {
50 	struct k_thread thread;
51 
52 	/* List nodes for pthread_cleanup_push() / pthread_cleanup_pop() */
53 	sys_slist_t cleanup_list;
54 
55 	/* List node for ready_q, run_q, or done_q */
56 	sys_dnode_t q_node;
57 
58 	/* List of keys that thread has called pthread_setspecific() on */
59 	sys_slist_t key_list;
60 
61 	/* pthread_attr_t */
62 	struct posix_thread_attr attr;
63 
64 	/* Exit status */
65 	void *retval;
66 
67 	/* Signal mask */
68 	sigset_t sigset;
69 
70 	/* Queue ID (internal-only) */
71 	uint8_t qid;
72 };
73 
74 struct posix_condattr {
75 	/* leaves room for CLOCK_REALTIME (1, default) and CLOCK_MONOTONIC (4) */
76 	unsigned char clock: 3;
77 	char initialized: 1;
78 #ifdef _POSIX_THREAD_PROCESS_SHARED
79 	unsigned char pshared: 1;
80 #endif
81 };
82 
83 struct posix_cond {
84 	struct k_condvar condvar;
85 	struct posix_condattr attr;
86 };
87 
88 typedef struct pthread_key_obj {
89 	/* List of pthread_key_data objects that contain thread
90 	 * specific data for the key
91 	 */
92 	sys_slist_t key_data_l;
93 
94 	/* Optional destructor that is passed to pthread_key_create() */
95 	void (*destructor)(void *value);
96 } pthread_key_obj;
97 
98 typedef struct pthread_thread_data {
99 	sys_snode_t node;
100 
101 	/* Key and thread specific data passed to pthread_setspecific() */
102 	pthread_key_obj *key;
103 	void *spec_data;
104 } pthread_thread_data;
105 
106 struct pthread_key_data {
107 	sys_snode_t node;
108 	pthread_thread_data thread_data;
109 };
110 
is_pthread_obj_initialized(uint32_t obj)111 static inline bool is_pthread_obj_initialized(uint32_t obj)
112 {
113 	return (obj & PTHREAD_OBJ_MASK_INIT) != 0;
114 }
115 
mark_pthread_obj_initialized(uint32_t obj)116 static inline uint32_t mark_pthread_obj_initialized(uint32_t obj)
117 {
118 	return obj | PTHREAD_OBJ_MASK_INIT;
119 }
120 
mark_pthread_obj_uninitialized(uint32_t obj)121 static inline uint32_t mark_pthread_obj_uninitialized(uint32_t obj)
122 {
123 	return obj & ~PTHREAD_OBJ_MASK_INIT;
124 }
125 
126 struct posix_thread *to_posix_thread(pthread_t pth);
127 
128 /* get and possibly initialize a posix_mutex */
129 struct k_mutex *to_posix_mutex(pthread_mutex_t *mu);
130 
131 int posix_to_zephyr_priority(int priority, int policy);
132 int zephyr_to_posix_priority(int priority, int *policy);
133 
134 #endif
135