Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / thread / waitcondition.c
blob31a5381a81c0027c686819a797621383f2653829
1 /*
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.
8 */
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>
17 #include <assert.h>
19 /*****************************************************************************
21 NAME */
22 AROS_LH2(BOOL, WaitCondition,
24 /* SYNOPSIS */
25 AROS_LHA(void *, cond, A0),
26 AROS_LHA(void *, mutex, A1),
28 /* LOCATION */
29 struct ThreadBase *, ThreadBase, 17, Thread)
31 /* FUNCTION
32 Blocks until a condition is signaled.
34 INPUTS
35 cond - the condition variable to wait on.
36 mutex - a mutex that protects the condition
38 RESULT
39 TRUE if the condition was signaled, FALSE if an error occured.
41 NOTES
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
49 more details.
51 EXAMPLE
52 LockMutex(mutex);
53 WaitCondition(cond, mutex);
54 UnlockMutex(mutex);
56 BUGS
58 SEE ALSO
59 CreateCondition(), DestroyCondition(), SignalCondition(),
60 BroadcastCondition()
62 INTERNALS
63 Waiting on a condition causes the current thread to wait to receive
64 SIGF_SINGLE from the signalling task.
66 *****************************************************************************/
68 AROS_LIBFUNC_INIT
70 struct _Condition *c = (struct _Condition *) cond;
71 struct _CondWaiter *waiter;
73 assert(c != NULL);
74 assert(mutex != NULL);
76 /* setup a new waiter */
77 if ((waiter = AllocMem(sizeof(struct _CondWaiter), MEMF_CLEAR)) == NULL) {
78 return FALSE;
80 waiter->task = FindTask(NULL);
82 /* safely add ourselves to the list of waiters */
83 ObtainSemaphore(&c->lock);
84 ADDTAIL(&c->waiters, waiter);
85 c->count++;
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 */
90 Forbid();
92 /* release the mutex that protects the condition */
93 UnlockMutex(mutex);
95 /* and now wait for someone to hit the condition. this will break the
96 * Forbid(), which is what we want */
97 Wait(SIGF_SINGLE);
99 /* the Forbid() is restored when Wait() exits, so we have to turn task
100 * switches on again. */
101 Permit();
103 /* retake the mutex */
104 LockMutex(mutex);
106 /* done. note that we're not removing ourselves from the list of waiters,
107 * that has been done by the signalling task */
108 return TRUE;
110 AROS_LIBFUNC_EXIT
111 } /* WaitCondition */