Skip to content

Commit 3e2c2c1

Browse files
committed
Put back threads.h polyfill for macOS;
1 parent 7afb46b commit 3e2c2c1

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ if(WIN32)
692692
elseif(APPLE)
693693
find_library(AVFOUNDATION AVFoundation)
694694
target_link_libraries(lovr objc ${AVFOUNDATION})
695+
target_include_directories(lovr PRIVATE ${PROJECT_SOURCE_DIR}/src/lib/std)
695696
target_sources(lovr PRIVATE src/core/os_macos.c)
696697
set_source_files_properties(src/core/os_macos.c PROPERTIES COMPILE_FLAGS -xobjective-c)
697698
set_target_properties(lovr PROPERTIES

src/lib/std/threads.h

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#ifdef __STDC_NO_THREADS__
2+
3+
#include <time.h>
4+
5+
#pragma once
6+
7+
typedef int (*thrd_start_t)(void*);
8+
9+
enum { thrd_success, thrd_nomem, thrd_timedout, thrd_busy, thrd_error };
10+
enum { mtx_plain };
11+
12+
#include <pthread.h>
13+
typedef pthread_t thrd_t;
14+
typedef pthread_mutex_t mtx_t;
15+
typedef pthread_cond_t cnd_t;
16+
#define thread_local _Thread_local
17+
18+
static inline int thrd_create(thrd_t* thread, thrd_start_t fn, void* arg);
19+
static inline int thrd_detach(thrd_t thread);
20+
static inline int thrd_join(thrd_t thread, int* result);
21+
static inline void thrd_yield(void);
22+
23+
static inline int mtx_init(mtx_t* mutex, int type);
24+
static inline void mtx_destroy(mtx_t* mutex);
25+
static inline int mtx_lock(mtx_t* mutex);
26+
static inline int mtx_unlock(mtx_t* mutex);
27+
28+
static inline int cnd_init(cnd_t* cond);
29+
static inline void cnd_destroy(cnd_t* cond);
30+
static inline int cnd_signal(cnd_t* cond);
31+
static inline int cnd_broadcast(cnd_t* cond);
32+
static inline int cnd_wait(cnd_t* cond, mtx_t* mutex);
33+
static inline int cnd_timedwait(cnd_t* restrict cond, mtx_t* restrict mutex, const struct timespec* restrict until);
34+
35+
// Implementation
36+
37+
typedef struct {
38+
thrd_start_t fn;
39+
void* arg;
40+
} thread_context;
41+
42+
#include <stdint.h>
43+
#include <stdlib.h>
44+
#include <errno.h>
45+
#include <sched.h>
46+
47+
static inline void* thread_main(void* arg) {
48+
thread_context ctx = *(thread_context*) arg;
49+
return free(arg), (void*) (intptr_t) ctx.fn(ctx.arg);
50+
}
51+
52+
static inline int thrd_create(thrd_t* thread, thrd_start_t fn, void* arg) {
53+
thread_context* ctx = malloc(sizeof(*ctx));
54+
if (!ctx) return thrd_nomem;
55+
56+
ctx->fn = fn;
57+
ctx->arg = arg;
58+
59+
if (pthread_create(thread, NULL, thread_main, ctx)) {
60+
free(ctx);
61+
return thrd_error;
62+
}
63+
64+
return thrd_success;
65+
}
66+
67+
static inline int thrd_detach(thrd_t thread) {
68+
return pthread_detach(thread) == 0 ? thrd_success : thrd_error;
69+
}
70+
71+
static inline int thrd_join(thrd_t thread, int* result) {
72+
void* p;
73+
if (pthread_join(thread, &p)) return thrd_error;
74+
if (result) *result = (int) (intptr_t) p;
75+
return thrd_success;
76+
}
77+
78+
static inline void thrd_yield(void) {
79+
sched_yield();
80+
}
81+
82+
static inline int mtx_init(mtx_t* mutex, int type) {
83+
return pthread_mutex_init(mutex, NULL) == 0 ? thrd_success : thrd_error;
84+
}
85+
86+
static inline void mtx_destroy(mtx_t* mutex) {
87+
pthread_mutex_destroy(mutex);
88+
}
89+
90+
static inline int mtx_lock(mtx_t* mutex) {
91+
return pthread_mutex_lock(mutex) == 0 ? thrd_success : thrd_error;
92+
}
93+
94+
static inline int mtx_unlock(mtx_t* mutex) {
95+
return pthread_mutex_unlock(mutex) == 0 ? thrd_success : thrd_error;
96+
}
97+
98+
static inline int cnd_init(cnd_t* cond) {
99+
return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
100+
}
101+
102+
static inline void cnd_destroy(cnd_t* cond) {
103+
pthread_cond_destroy(cond);
104+
}
105+
106+
static inline int cnd_signal(cnd_t* cond) {
107+
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
108+
}
109+
110+
static inline int cnd_broadcast(cnd_t* cond) {
111+
return pthread_cond_broadcast(cond) == 0 ? thrd_success : thrd_error;
112+
}
113+
114+
static inline int cnd_wait(cnd_t* cond, mtx_t* mutex) {
115+
return pthread_cond_wait(cond, mutex) == 0 ? thrd_success : thrd_error;
116+
}
117+
118+
static inline int cnd_timedwait(cnd_t* restrict cond, mtx_t* restrict mutex, const struct timespec* restrict until) {
119+
switch (pthread_cond_timedwait(cond, mutex, until)) {
120+
case ETIMEDOUT: return thrd_timedout;
121+
case 0: return thrd_success;
122+
default: return thrd_error;
123+
}
124+
}
125+
#else
126+
#include <threads.h>
127+
#endif

0 commit comments

Comments
 (0)