2 * AmigaOS thread syncronization primitives.
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>
15 #include <aros/debug.h>
17 #include LC_LIBDEFS_FILE
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
),
53 _condvar_wait_timeout
,
58 static int InitThreads(LIBBASETYPEPTR LIBBASE
)
60 dbus_threads_init(&amiga_functions
);
63 ADD2INITLIB(InitThreads
, 0)
65 static DBusMutex
* _mutex_new(void) {
66 struct SignalSemaphore
* mutex
= AllocVec(sizeof(struct SignalSemaphore
),
70 mutex
->ss_Link
.ln_Type
=NT_SIGNALSEM
;
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);
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
);
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
);
102 static DBusCondVar
* _condvar_new(void) {
103 struct CondVar
* cond
= AllocVec(sizeof(struct CondVar
),
104 MEMF_ANY
|MEMF_CLEAR
);
107 NewList((struct List
*) &cond
->Waiters
);
110 return (DBusCondVar
*) cond
;
113 static void _condvar_free(DBusCondVar
* c
) {
114 struct CondVar
* cond
= (struct CondVar
*) c
;
120 static void _condvar_wait(DBusCondVar
* c
, DBusMutex
* m
) {
121 struct CondVar
* cond
= (struct CondVar
*) c
;
123 struct SemaphoreRequest sr
= {
128 AddTail((struct List
*) &cond
->Waiters
, (struct Node
*) &sr
);
132 SetSignal(0, SIGF_SINGLE
);
138 Remove((struct Node
*) &sr
);
141 static dbus_bool_t
_condvar_wait_timeout(DBusCondVar
* c
, DBusMutex
* m
, int msec
) {
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
);