1 /*
2  * OpenBOR - http://www.chronocrash.com
3  * -----------------------------------------------------------------------
4  * All rights reserved, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2015 OpenBOR Team
7  */
8 
9 #include <stdlib.h>
10 #include <ogcsys.h>
11 #include <time.h>
12 #include "threads.h"
13 
14 #define LWP_RETCODE(X) ((X) == 0 ? 0 : -1)
15 
16 struct bor_thread {
17 	lwp_t thread;
18 	int (*run)(void *);
19 	void *data;
20 };
21 
run_thread(void * data)22 static void *run_thread(void *data)
23 {
24 	bor_thread *thread = (bor_thread*)data;
25 	return (void*)thread->run(thread->data);
26 }
27 
thread_create(int (* fn)(void *),const char * name,void * data)28 bor_thread *thread_create(int (*fn)(void *), const char *name, void *data)
29 {
30 	bor_thread *thread = malloc(sizeof(bor_thread));
31 	thread->run = fn;
32 	thread->data = data;
33 	LWP_CreateThread(&thread->thread, run_thread, thread, NULL, 0, 64);
34 	return thread;
35 }
36 
thread_join(bor_thread * thread)37 void thread_join(bor_thread *thread)
38 {
39 	void *status;
40 	LWP_JoinThread(thread->thread, &status);
41 	free(thread);
42 }
43 
mutex_create(void)44 bor_mutex *mutex_create(void)
45 {
46 	mutex_t *mutex = malloc(sizeof(mutex_t));
47 	if (LWP_MutexInit(mutex, 0) != 0) return NULL;
48 	return mutex;
49 }
50 
mutex_destroy(bor_mutex * mutex)51 void mutex_destroy(bor_mutex *mutex)
52 {
53 	LWP_MutexDestroy(*mutex);
54 	free(mutex);
55 }
56 
mutex_lock(bor_mutex * mutex)57 int mutex_lock(bor_mutex *mutex)
58 {
59 	return LWP_RETCODE(LWP_MutexLock(*mutex));
60 }
61 
mutex_unlock(bor_mutex * mutex)62 int mutex_unlock(bor_mutex *mutex)
63 {
64 	return LWP_RETCODE(LWP_MutexUnlock(*mutex));
65 }
66 
cond_create()67 bor_cond *cond_create()
68 {
69 	cond_t *cond = malloc(sizeof(cond_t));
70 	if (LWP_CondInit(cond) != 0) return NULL;
71 	return cond;
72 }
73 
cond_destroy(bor_cond * cond)74 void cond_destroy(bor_cond *cond)
75 {
76 	LWP_CondDestroy(*cond);
77 	free(cond);
78 }
79 
cond_signal(bor_cond * cond)80 int cond_signal(bor_cond *cond)
81 {
82 	return LWP_RETCODE(LWP_CondSignal(*cond));
83 }
84 
cond_broadcast(bor_cond * cond)85 int cond_broadcast(bor_cond *cond)
86 {
87 	return LWP_RETCODE(LWP_CondBroadcast(*cond));
88 }
89 
cond_wait(bor_cond * cond,bor_mutex * mutex)90 int cond_wait(bor_cond *cond, bor_mutex *mutex)
91 {
92 	return LWP_RETCODE(LWP_CondWait(*cond, *mutex));
93 }
94 
cond_wait_timed(bor_cond * cond,bor_mutex * mutex,int ms)95 int cond_wait_timed(bor_cond *cond, bor_mutex *mutex, int ms)
96 {
97 	struct timespec time_to_wait;
98 	time_to_wait.tv_sec = ms / 1000;
99 	time_to_wait.tv_nsec = ((long)(ms % 1000)) * 1000000;
100 	return LWP_RETCODE(LWP_CondTimedWait(*cond, *mutex, &time_to_wait));
101 }
102