| #include "cpython/pthread_stubs.h" | |
| typedef struct py_stub_tls_entry py_tls_entry; | |
| #define py_tls_entries (_PyRuntime.threads.stubs.tls_entries) | |
| // mutex | |
| int | |
| pthread_mutex_init(pthread_mutex_t *restrict mutex, | |
| const pthread_mutexattr_t *restrict attr) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_mutex_destroy(pthread_mutex_t *mutex) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_mutex_trylock(pthread_mutex_t *mutex) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_mutex_lock(pthread_mutex_t *mutex) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_mutex_unlock(pthread_mutex_t *mutex) | |
| { | |
| return 0; | |
| } | |
| // condition | |
| int | |
| pthread_cond_init(pthread_cond_t *restrict cond, | |
| const pthread_condattr_t *restrict attr) | |
| { | |
| return 0; | |
| } | |
| PyAPI_FUNC(int) pthread_cond_destroy(pthread_cond_t *cond) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_cond_wait(pthread_cond_t *restrict cond, | |
| pthread_mutex_t *restrict mutex) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_cond_timedwait(pthread_cond_t *restrict cond, | |
| pthread_mutex_t *restrict mutex, | |
| const struct timespec *restrict abstime) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_cond_signal(pthread_cond_t *cond) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_condattr_init(pthread_condattr_t *attr) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id) | |
| { | |
| return 0; | |
| } | |
| // pthread | |
| int | |
| pthread_create(pthread_t *restrict thread, | |
| const pthread_attr_t *restrict attr, | |
| void *(*start_routine)(void *), | |
| void *restrict arg) | |
| { | |
| return EAGAIN; | |
| } | |
| int | |
| pthread_detach(pthread_t thread) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_join(pthread_t thread, void** value_ptr) | |
| { | |
| if (value_ptr) { | |
| *value_ptr = NULL; | |
| } | |
| return 0; | |
| } | |
| PyAPI_FUNC(pthread_t) pthread_self(void) | |
| { | |
| return (pthread_t)(uintptr_t)&py_tls_entries; | |
| } | |
| int | |
| pthread_exit(void *retval) | |
| { | |
| exit(0); | |
| } | |
| int | |
| pthread_attr_init(pthread_attr_t *attr) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_attr_setstacksize( | |
| pthread_attr_t *attr, size_t stacksize) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_attr_destroy(pthread_attr_t *attr) | |
| { | |
| return 0; | |
| } | |
| int | |
| pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)) | |
| { | |
| if (!key) { | |
| return EINVAL; | |
| } | |
| if (destr_function != NULL) { | |
| Py_FatalError("pthread_key_create destructor is not supported"); | |
| } | |
| for (pthread_key_t idx = 0; idx < PTHREAD_KEYS_MAX; idx++) { | |
| if (!py_tls_entries[idx].in_use) { | |
| py_tls_entries[idx].in_use = true; | |
| *key = idx; | |
| return 0; | |
| } | |
| } | |
| return EAGAIN; | |
| } | |
| int | |
| pthread_key_delete(pthread_key_t key) | |
| { | |
| if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) { | |
| return EINVAL; | |
| } | |
| py_tls_entries[key].in_use = false; | |
| py_tls_entries[key].value = NULL; | |
| return 0; | |
| } | |
| void * | |
| pthread_getspecific(pthread_key_t key) { | |
| if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) { | |
| return NULL; | |
| } | |
| return py_tls_entries[key].value; | |
| } | |
| int | |
| pthread_setspecific(pthread_key_t key, const void *value) | |
| { | |
| if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) { | |
| return EINVAL; | |
| } | |
| py_tls_entries[key].value = (void *)value; | |
| return 0; | |
| } | |
| // let thread_pthread define the Python API | |
| #include "thread_pthread.h" |