2 * thread.library - threading and synchronisation primitives
4 * Copyright © 2007 Robert Norris
6 * This program is free software; you can redistribute it and/or modify it
7 * under the same terms as AROS itself.
10 #include "thread_intern.h"
12 #include <exec/tasks.h>
13 #include <exec/memory.h>
14 #include <exec/lists.h>
15 #include <proto/exec.h>
16 #include <proto/thread.h>
19 /*****************************************************************************
22 AROS_LH2(BOOL
, WaitCondition
,
25 AROS_LHA(void *, cond
, A0
),
26 AROS_LHA(void *, mutex
, A1
),
29 struct ThreadBase
*, ThreadBase
, 17, Thread
)
32 Blocks until a condition is signaled.
35 cond - the condition variable to wait on.
36 mutex - a mutex that protects the condition
39 TRUE if the condition was signaled, FALSE if an error occured.
42 This function will atomically unlock the mutex and wait on the
43 condition. The thread is suspended until the condition is signalled.
44 After the condition is signalled, the mutex is relocked before
45 returning to the caller.
47 The use of a mutex in conjunction with waiting on and signalling the
48 condition ensures that no signals are missed. See SignalCondition() for
53 WaitCondition(cond, mutex);
59 CreateCondition(), DestroyCondition(), SignalCondition(),
63 Waiting on a condition causes the current thread to wait to receive
64 SIGF_SINGLE from the signalling task.
66 *****************************************************************************/
70 struct _Condition
*c
= (struct _Condition
*) cond
;
71 struct _CondWaiter
*waiter
;
74 assert(mutex
!= NULL
);
76 /* setup a new waiter */
77 if ((waiter
= AllocMem(sizeof(struct _CondWaiter
), MEMF_CLEAR
)) == NULL
) {
80 waiter
->task
= FindTask(NULL
);
82 /* safely add ourselves to the list of waiters */
83 ObtainSemaphore(&c
->lock
);
84 ADDTAIL(&c
->waiters
, waiter
);
86 ReleaseSemaphore(&c
->lock
);
88 /* disable task switches. we must atomically unlock the mutex and wait for
89 * the signal, otherwise the signal may be missed */
92 /* release the mutex that protects the condition */
95 /* and now wait for someone to hit the condition. this will break the
96 * Forbid(), which is what we want */
99 /* the Forbid() is restored when Wait() exits, so we have to turn task
100 * switches on again. */
103 /* retake the mutex */
106 /* done. note that we're not removing ourselves from the list of waiters,
107 * that has been done by the signalling task */
111 } /* WaitCondition */