1 #include "cpython/pthread_stubs.h"
2 
3 // mutex
4 int
pthread_mutex_init(pthread_mutex_t * restrict mutex,const pthread_mutexattr_t * restrict attr)5 pthread_mutex_init(pthread_mutex_t *restrict mutex,
6                    const pthread_mutexattr_t *restrict attr)
7 {
8     return 0;
9 }
10 
11 int
pthread_mutex_destroy(pthread_mutex_t * mutex)12 pthread_mutex_destroy(pthread_mutex_t *mutex)
13 {
14     return 0;
15 }
16 
17 int
pthread_mutex_trylock(pthread_mutex_t * mutex)18 pthread_mutex_trylock(pthread_mutex_t *mutex)
19 {
20     return 0;
21 }
22 
23 int
pthread_mutex_lock(pthread_mutex_t * mutex)24 pthread_mutex_lock(pthread_mutex_t *mutex)
25 {
26     return 0;
27 }
28 
29 int
pthread_mutex_unlock(pthread_mutex_t * mutex)30 pthread_mutex_unlock(pthread_mutex_t *mutex)
31 {
32     return 0;
33 }
34 
35 // condition
36 int
pthread_cond_init(pthread_cond_t * restrict cond,const pthread_condattr_t * restrict attr)37 pthread_cond_init(pthread_cond_t *restrict cond,
38                   const pthread_condattr_t *restrict attr)
39 {
40     return 0;
41 }
42 
pthread_cond_destroy(pthread_cond_t * cond)43 PyAPI_FUNC(int)pthread_cond_destroy(pthread_cond_t *cond)
44 {
45     return 0;
46 }
47 
48 int
pthread_cond_wait(pthread_cond_t * restrict cond,pthread_mutex_t * restrict mutex)49 pthread_cond_wait(pthread_cond_t *restrict cond,
50                   pthread_mutex_t *restrict mutex)
51 {
52     return 0;
53 }
54 
55 int
pthread_cond_timedwait(pthread_cond_t * restrict cond,pthread_mutex_t * restrict mutex,const struct timespec * restrict abstime)56 pthread_cond_timedwait(pthread_cond_t *restrict cond,
57                        pthread_mutex_t *restrict mutex,
58                        const struct timespec *restrict abstime)
59 {
60     return 0;
61 }
62 
63 int
pthread_cond_signal(pthread_cond_t * cond)64 pthread_cond_signal(pthread_cond_t *cond)
65 {
66     return 0;
67 }
68 
69 int
pthread_condattr_init(pthread_condattr_t * attr)70 pthread_condattr_init(pthread_condattr_t *attr)
71 {
72     return 0;
73 }
74 
75 int
pthread_condattr_setclock(pthread_condattr_t * attr,clockid_t clock_id)76 pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)
77 {
78     return 0;
79 }
80 
81 // pthread
82 int
pthread_create(pthread_t * restrict thread,const pthread_attr_t * restrict attr,void * (* start_routine)(void *),void * restrict arg)83 pthread_create(pthread_t *restrict thread,
84                const pthread_attr_t *restrict attr,
85                void *(*start_routine)(void *),
86                void *restrict arg)
87 {
88     return EAGAIN;
89 }
90 
91 int
pthread_detach(pthread_t thread)92 pthread_detach(pthread_t thread)
93 {
94     return 0;
95 }
96 
pthread_self(void)97 PyAPI_FUNC(pthread_t) pthread_self(void)
98 {
99     return 0;
100 }
101 
102 int
pthread_exit(void * retval)103 pthread_exit(void *retval)
104 {
105     exit(0);
106 }
107 
108 int
pthread_attr_init(pthread_attr_t * attr)109 pthread_attr_init(pthread_attr_t *attr)
110 {
111     return 0;
112 }
113 
114 int
pthread_attr_setstacksize(pthread_attr_t * attr,size_t stacksize)115 pthread_attr_setstacksize(
116     pthread_attr_t *attr, size_t stacksize)
117 {
118     return 0;
119 }
120 
121 int
pthread_attr_destroy(pthread_attr_t * attr)122 pthread_attr_destroy(pthread_attr_t *attr)
123 {
124     return 0;
125 }
126 
127 // pthread_key
128 typedef struct {
129     bool in_use;
130     void *value;
131 } py_tls_entry;
132 
133 static py_tls_entry py_tls_entries[PTHREAD_KEYS_MAX] = {0};
134 
135 int
pthread_key_create(pthread_key_t * key,void (* destr_function)(void *))136 pthread_key_create(pthread_key_t *key, void (*destr_function)(void *))
137 {
138     if (!key) {
139         return EINVAL;
140     }
141     if (destr_function != NULL) {
142         Py_FatalError("pthread_key_create destructor is not supported");
143     }
144     for (pthread_key_t idx = 0; idx < PTHREAD_KEYS_MAX; idx++) {
145         if (!py_tls_entries[idx].in_use) {
146             py_tls_entries[idx].in_use = true;
147             *key = idx;
148             return 0;
149         }
150     }
151     return EAGAIN;
152 }
153 
154 int
pthread_key_delete(pthread_key_t key)155 pthread_key_delete(pthread_key_t key)
156 {
157     if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) {
158         return EINVAL;
159     }
160     py_tls_entries[key].in_use = false;
161     py_tls_entries[key].value = NULL;
162     return 0;
163 }
164 
165 
166 void *
pthread_getspecific(pthread_key_t key)167 pthread_getspecific(pthread_key_t key) {
168     if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) {
169         return NULL;
170     }
171     return py_tls_entries[key].value;
172 }
173 
174 int
pthread_setspecific(pthread_key_t key,const void * value)175 pthread_setspecific(pthread_key_t key, const void *value)
176 {
177     if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) {
178         return EINVAL;
179     }
180     py_tls_entries[key].value = (void *)value;
181     return 0;
182 }
183 
184 // let thread_pthread define the Python API
185 #include "thread_pthread.h"
186