32#if defined(__unix__) || defined(__APPLE__)
44# define THREAD_LOG(FMT, ...) DBG("THREAD", FMT __VA_OPT__(, ) __VA_ARGS__)
71static void *posix_trampoline(
void *arg) {
84 int rc = pthread_create(&t->
handle,
nullptr, posix_trampoline, t);
86 THREAD_LOG(
"pthread_create failed (errno %d)", rc);
88 return status_from_errno(rc);
97 if (sched_getaffinity(0,
sizeof(set), &set) == 0) {
98 int n = CPU_COUNT(&set);
104 long n = sysconf(_SC_NPROCESSORS_ONLN);
105 return n > 0 ? (size_t)
n : 1;
111 int rc = pthread_join(t->
handle,
nullptr);
113 THREAD_LOG(
"pthread_join failed (errno %d)", rc);
115 return status_from_errno(rc);
120 int rc = pthread_mutex_init(&m->
handle,
nullptr);
122 THREAD_LOG(
"pthread_mutex_init failed (errno %d)", rc);
124 return status_from_errno(rc);
129 int rc = pthread_mutex_lock(&m->
handle);
131 THREAD_LOG(
"pthread_mutex_lock failed (errno %d)", rc);
133 return status_from_errno(rc);
138 int rc = pthread_mutex_unlock(&m->
handle);
140 THREAD_LOG(
"pthread_mutex_unlock failed (errno %d)", rc);
142 return status_from_errno(rc);
147 int rc = pthread_mutex_destroy(&m->
handle);
149 THREAD_LOG(
"pthread_mutex_destroy failed (errno %d)", rc);
151 return status_from_errno(rc);
156 int rc = pthread_cond_init(&c->
handle,
nullptr);
158 THREAD_LOG(
"pthread_cond_init failed (errno %d)", rc);
160 return status_from_errno(rc);
168 THREAD_LOG(
"pthread_cond_wait failed (errno %d)", rc);
170 return status_from_errno(rc);
175 int rc = pthread_cond_signal(&c->
handle);
177 THREAD_LOG(
"pthread_cond_signal failed (errno %d)", rc);
179 return status_from_errno(rc);
184 int rc = pthread_cond_broadcast(&c->
handle);
186 THREAD_LOG(
"pthread_cond_broadcast failed (errno %d)", rc);
188 return status_from_errno(rc);
193 int rc = pthread_cond_destroy(&c->
handle);
195 THREAD_LOG(
"pthread_cond_destroy failed (errno %d)", rc);
197 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)
size_t srn_thread_cpu_count(void)
The number of CPUs the calling process may run threads on, at least 1.
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)