1#include "cpython/pthread_stubs.h"
2
3// mutex
4int
5pthread_mutex_init(pthread_mutex_t *restrict mutex,
6                   const pthread_mutexattr_t *restrict attr)
7{
8    return 0;
9}
10
11int
12pthread_mutex_destroy(pthread_mutex_t *mutex)
13{
14    return 0;
15}
16
17int
18pthread_mutex_trylock(pthread_mutex_t *mutex)
19{
20    return 0;
21}
22
23int
24pthread_mutex_lock(pthread_mutex_t *mutex)
25{
26    return 0;
27}
28
29int
30pthread_mutex_unlock(pthread_mutex_t *mutex)
31{
32    return 0;
33}
34
35// condition
36int
37pthread_cond_init(pthread_cond_t *restrict cond,
38                  const pthread_condattr_t *restrict attr)
39{
40    return 0;
41}
42
43PyAPI_FUNC(int)pthread_cond_destroy(pthread_cond_t *cond)
44{
45    return 0;
46}
47
48int
49pthread_cond_wait(pthread_cond_t *restrict cond,
50                  pthread_mutex_t *restrict mutex)
51{
52    return 0;
53}
54
55int
56pthread_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
63int
64pthread_cond_signal(pthread_cond_t *cond)
65{
66    return 0;
67}
68
69int
70pthread_condattr_init(pthread_condattr_t *attr)
71{
72    return 0;
73}
74
75int
76pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)
77{
78    return 0;
79}
80
81// pthread
82int
83pthread_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
91int
92pthread_detach(pthread_t thread)
93{
94    return 0;
95}
96
97PyAPI_FUNC(pthread_t) pthread_self(void)
98{
99    return 0;
100}
101
102int
103pthread_exit(void *retval)
104{
105    exit(0);
106}
107
108int
109pthread_attr_init(pthread_attr_t *attr)
110{
111    return 0;
112}
113
114int
115pthread_attr_setstacksize(
116    pthread_attr_t *attr, size_t stacksize)
117{
118    return 0;
119}
120
121int
122pthread_attr_destroy(pthread_attr_t *attr)
123{
124    return 0;
125}
126
127// pthread_key
128typedef struct {
129    bool in_use;
130    void *value;
131} py_tls_entry;
132
133static py_tls_entry py_tls_entries[PTHREAD_KEYS_MAX] = {0};
134
135int
136pthread_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
154int
155pthread_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
166void *
167pthread_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
174int
175pthread_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