]> git.xonotic.org Git - xonotic/darkplaces.git/blob - thread_sdl.c
qdefs: Define separate FLOAT_ and DOUBLE_ versions of lossless format and true for...
[xonotic/darkplaces.git] / thread_sdl.c
1 #include <SDL.h>
2 #include <SDL_thread.h>
3 #include "quakedef.h"
4 #include "thread.h"
5
6 int Thread_Init(void)
7 {
8 #ifdef THREADDISABLE
9         Con_Printf("Threading disabled in this build\n");
10 #endif
11         return 0;
12 }
13
14 void Thread_Shutdown(void)
15 {
16 }
17
18 qbool Thread_HasThreads(void)
19 {
20 #ifdef THREADDISABLE
21         return false;
22 #else
23         return true;
24 #endif
25 }
26
27 void *_Thread_CreateMutex(const char *filename, int fileline)
28 {
29         void *mutex = SDL_CreateMutex();
30 #ifdef THREADDEBUG
31         Sys_Printf("%p mutex create %s:%i\n" , mutex, filename, fileline);
32 #endif
33         return mutex;
34 }
35
36 void _Thread_DestroyMutex(void *mutex, const char *filename, int fileline)
37 {
38 #ifdef THREADDEBUG
39         Sys_Printf("%p mutex destroy %s:%i\n", mutex, filename, fileline);
40 #endif
41         SDL_DestroyMutex((SDL_mutex *)mutex);
42 }
43
44 int _Thread_LockMutex(void *mutex, const char *filename, int fileline)
45 {
46 #ifdef THREADDEBUG
47         Sys_Printf("%p mutex lock %s:%i\n"   , mutex, filename, fileline);
48 #endif
49         return SDL_LockMutex((SDL_mutex *)mutex);
50 }
51
52 int _Thread_UnlockMutex(void *mutex, const char *filename, int fileline)
53 {
54 #ifdef THREADDEBUG
55         Sys_Printf("%p mutex unlock %s:%i\n" , mutex, filename, fileline);
56 #endif
57         return SDL_UnlockMutex((SDL_mutex *)mutex);
58 }
59
60 void *_Thread_CreateCond(const char *filename, int fileline)
61 {
62         void *cond = (void *)SDL_CreateCond();
63 #ifdef THREADDEBUG
64         Sys_Printf("%p cond create %s:%i\n"   , cond, filename, fileline);
65 #endif
66         return cond;
67 }
68
69 void _Thread_DestroyCond(void *cond, const char *filename, int fileline)
70 {
71 #ifdef THREADDEBUG
72         Sys_Printf("%p cond destroy %s:%i\n"   , cond, filename, fileline);
73 #endif
74         SDL_DestroyCond((SDL_cond *)cond);
75 }
76
77 int _Thread_CondSignal(void *cond, const char *filename, int fileline)
78 {
79 #ifdef THREADDEBUG
80         Sys_Printf("%p cond signal %s:%i\n"   , cond, filename, fileline);
81 #endif
82         return SDL_CondSignal((SDL_cond *)cond);
83 }
84
85 int _Thread_CondBroadcast(void *cond, const char *filename, int fileline)
86 {
87 #ifdef THREADDEBUG
88         Sys_Printf("%p cond broadcast %s:%i\n"   , cond, filename, fileline);
89 #endif
90         return SDL_CondBroadcast((SDL_cond *)cond);
91 }
92
93 int _Thread_CondWait(void *cond, void *mutex, const char *filename, int fileline)
94 {
95 #ifdef THREADDEBUG
96         Sys_Printf("%p cond wait %s:%i\n"   , cond, filename, fileline);
97 #endif
98         return SDL_CondWait((SDL_cond *)cond, (SDL_mutex *)mutex);
99 }
100
101 void *_Thread_CreateThread(int (*fn)(void *), void *data, const char *filename, int fileline)
102 {
103         void *thread = (void *)SDL_CreateThread(fn, filename, data);
104 #ifdef THREADDEBUG
105         Sys_Printf("%p thread create %s:%i\n"   , thread, filename, fileline);
106 #endif
107         return thread;
108 }
109
110 int _Thread_WaitThread(void *thread, int retval, const char *filename, int fileline)
111 {
112         int status = retval;
113 #ifdef THREADDEBUG
114         Sys_Printf("%p thread wait %s:%i\n"   , thread, filename, fileline);
115 #endif
116         SDL_WaitThread((SDL_Thread *)thread, &status);
117         return status;
118 }
119
120 // standard barrier implementation using conds and mutexes
121 // see: http://www.howforge.com/implementing-barrier-in-pthreads
122 typedef struct {
123         unsigned int needed;
124         unsigned int called;
125         void *mutex;
126         void *cond;
127 } barrier_t;
128
129 void *_Thread_CreateBarrier(unsigned int count, const char *filename, int fileline)
130 {
131         volatile barrier_t *b = (volatile barrier_t *) Z_Malloc(sizeof(barrier_t));
132 #ifdef THREADDEBUG
133         Sys_Printf("%p barrier create(%d) %s:%i\n", b, count, filename, fileline);
134 #endif
135         b->needed = count;
136         b->called = 0;
137         b->mutex = Thread_CreateMutex();
138         b->cond = Thread_CreateCond();
139         return (void *) b;
140 }
141
142 void _Thread_DestroyBarrier(void *barrier, const char *filename, int fileline)
143 {
144         volatile barrier_t *b = (volatile barrier_t *) barrier;
145 #ifdef THREADDEBUG
146         Sys_Printf("%p barrier destroy %s:%i\n", b, filename, fileline);
147 #endif
148         Thread_DestroyMutex(b->mutex);
149         Thread_DestroyCond(b->cond);
150 }
151
152 void _Thread_WaitBarrier(void *barrier, const char *filename, int fileline)
153 {
154         volatile barrier_t *b = (volatile barrier_t *) barrier;
155 #ifdef THREADDEBUG
156         Sys_Printf("%p barrier wait %s:%i\n", b, filename, fileline);
157 #endif
158         Thread_LockMutex(b->mutex);
159         b->called++;
160         if (b->called == b->needed) {
161                 b->called = 0;
162                 Thread_CondBroadcast(b->cond);
163         } else {
164                 do {
165                         Thread_CondWait(b->cond, b->mutex);
166                 } while(b->called);
167         }
168         Thread_UnlockMutex(b->mutex);
169 }
170
171 int _Thread_AtomicGet(Thread_Atomic *a, const char *filename, int fileline)
172 {
173 #ifdef THREADDEBUG
174         Sys_Printf("%p atomic get at %s:%i\n", a, filename, fileline);
175 #endif
176         return SDL_AtomicGet((SDL_atomic_t *)a);
177 }
178
179 int _Thread_AtomicSet(Thread_Atomic *a, int v, const char *filename, int fileline)
180 {
181 #ifdef THREADDEBUG
182         Sys_Printf("%p atomic set %v at %s:%i\n", a, v, filename, fileline);
183 #endif
184         return SDL_AtomicSet((SDL_atomic_t *)a, v);
185 }
186
187 int _Thread_AtomicAdd(Thread_Atomic *a, int v, const char *filename, int fileline)
188 {
189 #ifdef THREADDEBUG
190         Sys_Printf("%p atomic add %v at %s:%i\n", a, v, filename, fileline);
191 #endif
192         return SDL_AtomicAdd((SDL_atomic_t *)a, v);
193 }
194
195 void _Thread_AtomicIncRef(Thread_Atomic *a, const char *filename, int fileline)
196 {
197 #ifdef THREADDEBUG
198         Sys_Printf("%p atomic incref %s:%i\n", a, filename, fileline);
199 #endif
200         SDL_AtomicIncRef((SDL_atomic_t *)a);
201 }
202
203 qbool _Thread_AtomicDecRef(Thread_Atomic *a, const char *filename, int fileline)
204 {
205 #ifdef THREADDEBUG
206         Sys_Printf("%p atomic decref %s:%i\n", a, filename, fileline);
207 #endif
208         return SDL_AtomicDecRef((SDL_atomic_t *)a) != SDL_FALSE;
209 }
210
211 qbool _Thread_AtomicTryLock(Thread_SpinLock *lock, const char *filename, int fileline)
212 {
213 #ifdef THREADDEBUG
214         Sys_Printf("%p atomic try lock %s:%i\n", lock, filename, fileline);
215 #endif
216         return SDL_AtomicTryLock(lock) != SDL_FALSE;
217 }
218
219 void _Thread_AtomicLock(Thread_SpinLock *lock, const char *filename, int fileline)
220 {
221 #ifdef THREADDEBUG
222         Sys_Printf("%p atomic lock %s:%i\n", lock, filename, fileline);
223 #endif
224         SDL_AtomicLock(lock);
225 }
226
227 void _Thread_AtomicUnlock(Thread_SpinLock *lock, const char *filename, int fileline)
228 {
229 #ifdef THREADDEBUG
230         Sys_Printf("%p atomic unlock %s:%i\n", lock, filename, fileline);
231 #endif
232         SDL_AtomicUnlock(lock);
233 }