Commit of the code which was suggested by Georg as a fix for:
[cake.git] / rom / exec / signal.c
blob0b989f146e0f9c9a459511de52875bd587b94035
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Send some signal to a given task
6 Lang: english
7 */
8 #include <exec/execbase.h>
9 #include <aros/libcall.h>
10 #include <proto/exec.h>
11 #include <aros/debug.h>
13 /*****************************************************************************
15 NAME */
17 AROS_LH2(void, Signal,
19 /* SYNOPSIS */
20 AROS_LHA(struct Task *, task, A1),
21 AROS_LHA(ULONG, signalSet, D0),
23 /* LOCATION */
24 struct ExecBase *, SysBase, 54, Exec)
26 /* FUNCTION
27 Send some signals to a given task. If the task is currently waiting
28 on these signals, has a higher priority as the current one and if
29 taskswitches are allowed the new task begins to run immediately.
31 INPUTS
32 task - Pointer to task structure.
33 signalSet - The set of signals to send to the task.
35 RESULT
37 NOTES
38 This function may be used from interrupts.
40 EXAMPLE
42 BUGS
44 SEE ALSO
45 AllocSignal(), FreeSignal(), Wait(), SetSignal(), SetExcept()
47 INTERNALS
49 ******************************************************************************/
51 AROS_LIBFUNC_INIT
53 /* Protect the task lists against other tasks that may use Signal(). */
54 Disable();
56 /* Set the signals in the task structure. */
57 task->tc_SigRecvd|=signalSet;
59 /* Do those bits raise exceptions? */
60 if(task->tc_SigExcept&task->tc_SigRecvd)
62 /* Yes. Set the exception flag. */
63 task->tc_Flags|=TF_EXCEPT;
65 /* task is running? Raise the exception or defer it for later. */
66 if(task->tc_State==TS_RUN)
68 /* Are taskswitches allowed? (Don't count own Disable() here) */
69 if(SysBase->TDNestCnt>=0||SysBase->IDNestCnt>0)
70 /* No. Store it for later. */
71 SysBase->AttnResched|=0x80;
72 else
74 /* Switches are allowed. Move the current task away. */
75 SysBase->ThisTask->tc_State=TS_READY;
76 Enqueue(&SysBase->TaskReady,&SysBase->ThisTask->tc_Node);
78 /* And force a rescedule. */
79 Switch();
82 /* All done. */
83 Enable();
84 return;
89 Is the task receiving the signals waiting on them
90 (or on a exception) ?
92 if(task->tc_State==TS_WAIT&&
93 (task->tc_SigRecvd&(task->tc_SigWait|task->tc_SigExcept)))
95 /* Yes. Move him to the ready list. */
96 task->tc_State=TS_READY;
97 Remove(&task->tc_Node);
98 Enqueue(&SysBase->TaskReady,&task->tc_Node);
100 /* Has it a higher priority as the current one? */
101 if(task->tc_Node.ln_Pri>SysBase->ThisTask->tc_Node.ln_Pri)
104 Yes. A taskswitch is necessary. Prepare one if possible.
105 (If the current task is not running it is already moved)
107 if(SysBase->ThisTask->tc_State==TS_RUN)
109 /* Are taskswitches allowed? */
110 if(SysBase->TDNestCnt>=0||SysBase->IDNestCnt>0)
112 /* No. Store it for later. */
113 SysBase->AttnResched|=0x80;
115 else
117 /* Switches are allowed. Move the current task away. */
118 SysBase->ThisTask->tc_State=TS_READY;
119 Enqueue(&SysBase->TaskReady,&SysBase->ThisTask->tc_Node);
121 /* And force a rescedule. */
122 Switch();
128 Enable();
129 AROS_LIBFUNC_EXIT
130 } /* Signal() */