10 void Thread_Shutdown(void)
14 qboolean Thread_HasThreads(void)
19 void *_Thread_CreateMutex(const char *filename, int fileline)
21 void *mutex = (void *)CreateMutex(NULL, FALSE, NULL);
23 Sys_PrintfToTerminal("%p mutex create %s:%i\n" , mutex, filename, fileline);
28 void _Thread_DestroyMutex(void *mutex, const char *filename, int fileline)
31 Sys_PrintfToTerminal("%p mutex destroy %s:%i\n", mutex, filename, fileline);
36 int _Thread_LockMutex(void *mutex, const char *filename, int fileline)
39 Sys_PrintfToTerminal("%p mutex lock %s:%i\n" , mutex, filename, fileline);
41 return (WaitForSingleObject(mutex, INFINITE) == WAIT_FAILED) ? -1 : 0;
44 int _Thread_UnlockMutex(void *mutex, const char *filename, int fileline)
47 Sys_PrintfToTerminal("%p mutex unlock %s:%i\n" , mutex, filename, fileline);
49 return (ReleaseMutex(mutex) == FALSE) ? -1 : 0;
52 typedef struct thread_semaphore_s
59 static thread_semaphore_t *Thread_CreateSemaphore(unsigned int v)
61 thread_semaphore_t *s = (thread_semaphore_t *)calloc(sizeof(*s), 1);
62 s->semaphore = CreateSemaphore(NULL, v, 32768, NULL);
67 static void Thread_DestroySemaphore(thread_semaphore_t *s)
69 CloseHandle(s->semaphore);
73 static int Thread_WaitSemaphore(thread_semaphore_t *s, unsigned int msec)
75 int r = WaitForSingleObject(s->semaphore, msec);
76 if (r == WAIT_OBJECT_0)
78 InterlockedDecrement(&s->value);
81 if (r == WAIT_TIMEOUT)
86 static int Thread_PostSemaphore(thread_semaphore_t *s)
88 InterlockedIncrement(&s->value);
89 if (ReleaseSemaphore(s->semaphore, 1, NULL))
91 InterlockedDecrement(&s->value);
95 typedef struct thread_cond_s
100 thread_semaphore_t *sem;
101 thread_semaphore_t *done;
105 void *_Thread_CreateCond(const char *filename, int fileline)
107 thread_cond_t *c = (thread_cond_t *)calloc(sizeof(*c), 1);
108 c->mutex = CreateMutex(NULL, FALSE, NULL);
109 c->sem = Thread_CreateSemaphore(0);
110 c->done = Thread_CreateSemaphore(0);
114 Sys_PrintfToTerminal("%p cond create %s:%i\n" , c, filename, fileline);
119 void _Thread_DestroyCond(void *cond, const char *filename, int fileline)
121 thread_cond_t *c = (thread_cond_t *)cond;
123 Sys_PrintfToTerminal("%p cond destroy %s:%i\n" , cond, filename, fileline);
125 Thread_DestroySemaphore(c->sem);
126 Thread_DestroySemaphore(c->done);
127 CloseHandle(c->mutex);
130 int _Thread_CondSignal(void *cond, const char *filename, int fileline)
132 thread_cond_t *c = (thread_cond_t *)cond;
135 Sys_PrintfToTerminal("%p cond signal %s:%i\n" , cond, filename, fileline);
137 WaitForSingleObject(c->mutex, INFINITE);
138 n = c->waiting - c->signals;
142 Thread_PostSemaphore(c->sem);
144 ReleaseMutex(c->mutex);
146 Thread_WaitSemaphore(c->done, INFINITE);
150 int _Thread_CondBroadcast(void *cond, const char *filename, int fileline)
152 thread_cond_t *c = (thread_cond_t *)cond;
156 Sys_PrintfToTerminal("%p cond broadcast %s:%i\n" , cond, filename, fileline);
158 WaitForSingleObject(c->mutex, INFINITE);
159 n = c->waiting - c->signals;
163 for (i = 0;i < n;i++)
164 Thread_PostSemaphore(c->sem);
166 ReleaseMutex(c->mutex);
167 for (i = 0;i < n;i++)
168 Thread_WaitSemaphore(c->done, INFINITE);
172 int _Thread_CondWait(void *cond, void *mutex, const char *filename, int fileline)
174 thread_cond_t *c = (thread_cond_t *)cond;
177 Sys_PrintfToTerminal("%p cond wait %s:%i\n" , cond, filename, fileline);
180 WaitForSingleObject(c->mutex, INFINITE);
182 ReleaseMutex(c->mutex);
186 waitresult = Thread_WaitSemaphore(c->sem, INFINITE);
187 WaitForSingleObject(c->mutex, INFINITE);
191 Thread_WaitSemaphore(c->sem, INFINITE);
192 Thread_PostSemaphore(c->done);
196 ReleaseMutex(c->mutex);
198 WaitForSingleObject(mutex, INFINITE);
202 typedef struct threadwrapper_s
205 unsigned int threadid;
212 unsigned int __stdcall Thread_WrapperFunc(void *d)
214 threadwrapper_t *w = (threadwrapper_t *)d;
215 w->result = w->fn(w->data);
216 _endthreadex(w->result);
220 void *_Thread_CreateThread(int (*fn)(void *), void *data, const char *filename, int fileline)
222 threadwrapper_t *w = (threadwrapper_t *)calloc(sizeof(*w), 1);
224 Sys_PrintfToTerminal("%p thread create %s:%i\n" , w, filename, fileline);
230 w->handle = (HANDLE)_beginthreadex(NULL, 0, Thread_WrapperFunc, (void *)w, 0, &w->threadid);
234 int _Thread_WaitThread(void *d, int retval, const char *filename, int fileline)
236 threadwrapper_t *w = (threadwrapper_t *)d;
238 Sys_PrintfToTerminal("%p thread wait %s:%i\n" , w, filename, fileline);
240 WaitForSingleObject(w->handle, INFINITE);
241 CloseHandle(w->handle);