32#if defined(__unix__) || defined(__APPLE__)
39# define THREAD_LOG(FMT, ...) DBG("THREAD", FMT __VA_OPT__(, ) __VA_ARGS__)
66static void *posix_trampoline(
void *arg) {
79 int rc = pthread_create(&t->
handle,
nullptr, posix_trampoline, t);
81 THREAD_LOG(
"pthread_create failed (errno %d)", rc);
83 return status_from_errno(rc);
89 int rc = pthread_join(t->
handle,
nullptr);
91 THREAD_LOG(
"pthread_join failed (errno %d)", rc);
93 return status_from_errno(rc);
98 int rc = pthread_mutex_init(&m->
handle,
nullptr);
100 THREAD_LOG(
"pthread_mutex_init failed (errno %d)", rc);
102 return status_from_errno(rc);
107 int rc = pthread_mutex_lock(&m->
handle);
109 THREAD_LOG(
"pthread_mutex_lock failed (errno %d)", rc);
111 return status_from_errno(rc);
116 int rc = pthread_mutex_unlock(&m->
handle);
118 THREAD_LOG(
"pthread_mutex_unlock failed (errno %d)", rc);
120 return status_from_errno(rc);
125 int rc = pthread_mutex_destroy(&m->
handle);
127 THREAD_LOG(
"pthread_mutex_destroy failed (errno %d)", rc);
129 return status_from_errno(rc);
134 int rc = pthread_cond_init(&c->
handle,
nullptr);
136 THREAD_LOG(
"pthread_cond_init failed (errno %d)", rc);
138 return status_from_errno(rc);
146 THREAD_LOG(
"pthread_cond_wait failed (errno %d)", rc);
148 return status_from_errno(rc);
153 int rc = pthread_cond_signal(&c->
handle);
155 THREAD_LOG(
"pthread_cond_signal failed (errno %d)", rc);
157 return status_from_errno(rc);
162 int rc = pthread_cond_broadcast(&c->
handle);
164 THREAD_LOG(
"pthread_cond_broadcast failed (errno %d)", rc);
166 return status_from_errno(rc);
171 int rc = pthread_cond_destroy(&c->
handle);
173 THREAD_LOG(
"pthread_cond_destroy failed (errno %d)", rc);
175 return status_from_errno(rc);
void(* fn)(void *)
The function the thread runs and its argument, recorded by srn_thread_spawn and read once by the back...
srn_thread_t, srn_mutex_t, and srn_cond_t model the thread-level operations the runtime needs,...
srn_thread_status_t srn_mutex_destroy(srn_mutex_t *m)
Release a mutex's resources.
srn_thread_status_t srn_mutex_init(srn_mutex_t *m)
srn_thread_status_t srn_cond_destroy(srn_cond_t *c)
Release a condition's resources.
srn_thread_status_t srn_thread_join(srn_thread_t *t)
Block until the thread started for t returns.
srn_thread_status_t srn_mutex_unlock(srn_mutex_t *m)
srn_thread_status_t
Result of a thread operation.
@ SRN_THREAD_AGAIN
The system lacked the resources to start the thread, such as a per-process thread limit.
@ SRN_THREAD_ERROR
A failure the backend could not map to the above.
@ SRN_THREAD_PERM
The caller lacks permission for the requested operation.
@ SRN_THREAD_NOMEM
Out of memory.
srn_thread_status_t srn_cond_wait(srn_cond_t *c, srn_mutex_t *m)
Release m, sleep until notified, then re-acquire m before returning.
srn_thread_status_t srn_mutex_lock(srn_mutex_t *m)
srn_thread_status_t srn_cond_init(srn_cond_t *c)
srn_thread_status_t srn_cond_notify_one(srn_cond_t *c)
Wake one waiter.
srn_thread_status_t srn_cond_notify_all(srn_cond_t *c)
Wake every waiter.
srn_thread_status_t srn_thread_spawn(srn_thread_t *t, void(*fn)(void *), void *arg)
Run fn(arg) on a new OS thread.
#define PANIC_IF_NULL(ptr)