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 	bool contentionscope: 1;
33 	bool inheritsched: 1;
34 	union {
35 		bool caller_destroys: 1;
36 		bool initialized: 1;
37 	};
38 	bool cancelpending: 1;
39 	bool cancelstate: 1;
40 	bool canceltype: 1;
41 	bool detachstate: 1;
42 };
43 
44 struct posix_thread {
45 	struct k_thread thread;
46 
47 	/* List nodes for pthread_cleanup_push() / pthread_cleanup_pop() */
48 	sys_slist_t cleanup_list;
49 
50 	/* List node for ready_q, run_q, or done_q */
51 	sys_dnode_t q_node;
52 
53 	/* List of keys that thread has called pthread_setspecific() on */
54 	sys_slist_t key_list;
55 
56 	/* pthread_attr_t */
57 	struct posix_thread_attr attr;
58 
59 	/* Exit status */
60 	void *retval;
61 
62 	/* Signal mask */
63 	sigset_t sigset;
64 
65 	/* Queue ID (internal-only) */
66 	uint8_t qid;
67 };
68 
69 typedef struct pthread_key_obj {
70 	/* List of pthread_key_data objects that contain thread
71 	 * specific data for the key
72 	 */
73 	sys_slist_t key_data_l;
74 
75 	/* Optional destructor that is passed to pthread_key_create() */
76 	void (*destructor)(void *value);
77 } pthread_key_obj;
78 
79 typedef struct pthread_thread_data {
80 	sys_snode_t node;
81 
82 	/* Key and thread specific data passed to pthread_setspecific() */
83 	pthread_key_obj *key;
84 	void *spec_data;
85 } pthread_thread_data;
86 
87 struct pthread_key_data {
88 	sys_snode_t node;
89 	pthread_thread_data thread_data;
90 };
91 
is_pthread_obj_initialized(uint32_t obj)92 static inline bool is_pthread_obj_initialized(uint32_t obj)
93 {
94 	return (obj & PTHREAD_OBJ_MASK_INIT) != 0;
95 }
96 
mark_pthread_obj_initialized(uint32_t obj)97 static inline uint32_t mark_pthread_obj_initialized(uint32_t obj)
98 {
99 	return obj | PTHREAD_OBJ_MASK_INIT;
100 }
101 
mark_pthread_obj_uninitialized(uint32_t obj)102 static inline uint32_t mark_pthread_obj_uninitialized(uint32_t obj)
103 {
104 	return obj & ~PTHREAD_OBJ_MASK_INIT;
105 }
106 
107 struct posix_thread *to_posix_thread(pthread_t pth);
108 
109 /* get and possibly initialize a posix_mutex */
110 struct k_mutex *to_posix_mutex(pthread_mutex_t *mu);
111 
112 int posix_to_zephyr_priority(int priority, int policy);
113 int zephyr_to_posix_priority(int priority, int *policy);
114 
115 #endif
116