- Inserted some USB3 hub class request skeletons
[AROS.git] / rom / exec / wait.c
blob70d317fbadd1f49bfaf3017db3493f3704967a27
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Wait for some signal.
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
12 #include <exec/execbase.h>
13 #include <aros/libcall.h>
14 #include <proto/exec.h>
16 #include "exec_intern.h"
17 #if defined(__AROSEXEC_SMP__)
18 #include "etask.h"
19 #endif
21 /*****************************************************************************
23 NAME */
25 AROS_LH1(ULONG, Wait,
27 /* SYNOPSIS */
28 AROS_LHA(ULONG, signalSet, D0),
30 /* LOCATION */
31 struct ExecBase *, SysBase, 53, Exec)
33 /* FUNCTION
34 Wait until some signals are sent to the current task. If any signal
35 of the specified set is already set when entering this function it
36 returns immediately. Since almost any event in the OS can send a
37 signal to your task if you specify it to do so signals are a very
38 powerful mechanism.
40 INPUTS
41 signalSet - The set of signals to wait for.
43 RESULT
44 The set of active signals.
46 NOTES
47 Naturally it's not allowed to wait in supervisor mode.
49 Calling Wait() breaks an active Disable() or Forbid().
51 EXAMPLE
53 BUGS
55 SEE ALSO
56 Signal(), SetSignal(), AllocSignal(), FreeSignal()
58 INTERNALS
60 HISTORY
62 ******************************************************************************/
64 AROS_LIBFUNC_INIT
66 struct Task *thisTask = GET_THIS_TASK;
67 ULONG rcvd;
69 D(bug("[Exec] Wait(%08lX)\n", signalSet);)
70 Disable();
72 /* If at least one of the signals is already set do not wait. */
73 while (!(thisTask->tc_SigRecvd & signalSet))
75 /* Set the wait signal mask */
76 thisTask->tc_SigWait = signalSet;
78 D(bug("[Exec] Wait: Moving '%s' @ 0x%p to Task Wait queue\n", thisTask->tc_Node.ln_Name, thisTask);)
79 D(bug("[Exec] Wait: Task state = %08x\n", thisTask->tc_State);)
82 Clear TDNestCnt (because Switch() will not care about it),
83 but memorize it first. IDNestCnt is handled by Switch().
85 thisTask->tc_TDNestCnt = TDNESTCOUNT_GET;
86 D(bug("[Exec] Wait: Task TDNestCount = %d\n", thisTask->tc_TDNestCnt);)
87 TDNESTCOUNT_SET(-1);
89 thisTask->tc_State = TS_WAIT;
90 // nb: on smp builds switch will move us.
91 #if !defined(__AROSEXEC_SMP__)
92 /* Move current task to the waiting list. */
93 Enqueue(&SysBase->TaskWait, &thisTask->tc_Node);
94 #endif
96 /* And switch to the next ready task. */
97 KrnSwitch();
100 OK. Somebody awakened us. This means that either the
101 signals are there or it's just a finished task exception.
102 Test again to be sure (see above).
104 D(bug("[Exec] Wait: Awoken...\n");)
106 /* Restore TDNestCnt. */
107 TDNESTCOUNT_SET(thisTask->tc_TDNestCnt);
109 /* Get active signals. */
110 rcvd = (thisTask->tc_SigRecvd & signalSet);
112 /* And clear them. */
113 #if defined(__AROSEXEC_SMP__)
114 __AROS_ATOMIC_AND_L(thisTask->tc_SigRecvd, ~signalSet);
115 #else
116 thisTask->tc_SigRecvd &= ~signalSet;
117 #endif
118 Enable();
120 /* All done. */
121 return rcvd;
123 AROS_LIBFUNC_EXIT