Check for SYS/GL during library init. Reason is that
[AROS.git] / rom / dbus / amiga_threads.c
blob5f09b176a3769b76cddeb8cc07f201cb89a9a711
1 /*
2 * AmigaOS thread syncronization primitives.
3 */
5 #include <exec/memory.h>
6 #include <exec/semaphores.h>
8 #include <clib/alib_protos.h>
9 #include <proto/dbus.h>
10 #include <proto/exec.h>
12 #include <aros/symbolsets.h>
14 #define DEBUG 1
15 #include <aros/debug.h>
17 #include LC_LIBDEFS_FILE
19 struct CondVar {
20 struct MinList Waiters;
23 static DBusMutex* _mutex_new(void);
24 static void _mutex_free(DBusMutex*);
25 static dbus_bool_t _mutex_lock(DBusMutex*);
26 static dbus_bool_t _mutex_unlock(DBusMutex*);
28 static DBusCondVar* _condvar_new(void);
29 static void _condvar_free(DBusCondVar*);
30 static void _condvar_wait(DBusCondVar*, DBusMutex*);
31 static dbus_bool_t _condvar_wait_timeout (DBusCondVar*, DBusMutex*, int);
32 static void _condvar_wake_one (DBusCondVar*);
33 static void _condvar_wake_all (DBusCondVar*);
35 static const DBusThreadFunctions amiga_functions = {
36 (DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
37 DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
38 DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
39 DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
40 DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
41 DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
42 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
43 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
44 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
45 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK),
46 _mutex_new,
47 _mutex_free,
48 _mutex_lock,
49 _mutex_unlock,
50 _condvar_new,
51 _condvar_free,
52 _condvar_wait,
53 _condvar_wait_timeout,
54 _condvar_wake_one,
55 _condvar_wake_all,
58 static int InitThreads(LIBBASETYPEPTR LIBBASE)
60 dbus_threads_init(&amiga_functions);
61 return TRUE;
63 ADD2INITLIB(InitThreads, 0)
65 static DBusMutex* _mutex_new(void) {
66 struct SignalSemaphore* mutex = AllocVec(sizeof(struct SignalSemaphore),
67 MEMF_ANY|MEMF_CLEAR);
69 if (mutex != NULL) {
70 mutex->ss_Link.ln_Type=NT_SIGNALSEM;
71 InitSemaphore(mutex);
74 // kprintf("_mutex_new returns %08lx\n", mutex);
75 return (DBusMutex*) mutex;
78 static void _mutex_free(DBusMutex* m) {
79 struct SignalSemaphore* mutex = (struct SignalSemaphore*) m;
81 // kprintf("_mutex_free %08lx\n", mutex);
82 FreeVec(mutex);
85 static dbus_bool_t _mutex_lock(DBusMutex* m) {
86 struct SignalSemaphore* mutex = (struct SignalSemaphore*) m;
88 // kprintf("_mutex_lock %08lx\n", mutex);
89 ObtainSemaphore(mutex);
90 return TRUE;
93 static dbus_bool_t _mutex_unlock(DBusMutex* m) {
94 struct SignalSemaphore* mutex = (struct SignalSemaphore*) m;
96 // kprintf("_mutex_unlock %08lx\n", mutex);
97 ReleaseSemaphore(mutex);
98 return TRUE;
102 static DBusCondVar* _condvar_new(void) {
103 struct CondVar* cond = AllocVec(sizeof(struct CondVar),
104 MEMF_ANY|MEMF_CLEAR);
106 if (cond != NULL) {
107 NewList((struct List*) &cond->Waiters);
110 return (DBusCondVar*) cond;
113 static void _condvar_free(DBusCondVar* c) {
114 struct CondVar* cond = (struct CondVar*) c;
116 FreeVec(cond);
120 static void _condvar_wait(DBusCondVar* c, DBusMutex* m) {
121 struct CondVar* cond = (struct CondVar*) c;
123 struct SemaphoreRequest sr = {
124 { NULL, NULL },
125 FindTask(NULL)
128 AddTail((struct List*) &cond->Waiters, (struct Node*) &sr);
130 Forbid();
131 _mutex_unlock(m);
132 SetSignal(0, SIGF_SINGLE);
133 Permit();
135 Wait(SIGF_SINGLE);
137 _mutex_lock(m);
138 Remove((struct Node*) &sr);
141 static dbus_bool_t _condvar_wait_timeout(DBusCondVar* c, DBusMutex* m, int msec) {
142 /* TODO */
143 _condvar_wait(c, m);
145 return TRUE;
148 static void _condvar_wake_one (DBusCondVar* c) {
149 struct CondVar* cond = (struct CondVar*) c;
151 /* Assume the mutex is locked */
152 if (!IsListEmpty((struct List*) &cond->Waiters)) {
153 Signal(((struct SemaphoreRequest*) cond->Waiters.mlh_Head)->sr_Waiter, SIGF_SINGLE);
157 static void _condvar_wake_all (DBusCondVar* c) {
158 struct CondVar* cond = (struct CondVar*) c;
159 struct SemaphoreRequest* sr;
161 /* Assume the mutex is locked */
162 for (sr = (struct SemaphoreRequest*) cond->Waiters.mlh_Head;
163 sr->sr_Link.mln_Succ != NULL;
164 sr = (struct SemaphoreRequest*) sr->sr_Link.mln_Succ) {
165 Signal(sr->sr_Waiter, SIGF_SINGLE);