2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
5 Desc: Send some signal to a given task
10 #include <aros/debug.h>
11 #include <exec/execbase.h>
12 #include <aros/libcall.h>
13 #include <proto/exec.h>
15 #include "exec_intern.h"
16 #if defined(__AROSEXEC_SMP__)
17 #include <proto/kernel.h>
21 /*****************************************************************************
25 AROS_LH2(void, Signal
,
28 AROS_LHA(struct Task
*, task
, A1
),
29 AROS_LHA(ULONG
, signalSet
, D0
),
32 struct ExecBase
*, SysBase
, 54, Exec
)
35 Send some signals to a given task. If the task is currently waiting
36 on these signals, has a higher priority as the current one and if
37 taskswitches are allowed the new task begins to run immediately.
40 task - Pointer to task structure.
41 signalSet - The set of signals to send to the task.
46 This function may be used from interrupts.
53 AllocSignal(), FreeSignal(), Wait(), SetSignal(), SetExcept()
59 ******************************************************************************/
63 struct Task
*ThisTask
= GET_THIS_TASK
;
64 #if defined(__AROSEXEC_SMP__)
65 spinlock_t
*task_listlock
= NULL
;
66 int cpunum
= KrnGetCPUNumber();
70 bug("[Exec] Signal(0x%p, %08lX)\n", task
, signalSet
);
71 bug("[Exec] Signal: signaling '%s' (state %08x)\n", task
->tc_Node
.ln_Name
, task
->tc_State
);
72 bug("[Exec] Signal: from '%s'\n", ThisTask
->tc_Node
.ln_Name
);
75 #if defined(__AROSEXEC_SMP__)
76 EXEC_SPINLOCK_LOCK(&IntETask(ThisTask
->tc_UnionETask
.tc_ETask
)->iet_TaskLock
, SPINLOCK_MODE_WRITE
);
79 /* Set the signals in the task structure. */
80 task
->tc_SigRecvd
|= signalSet
;
81 #if defined(__AROSEXEC_SMP__)
82 EXEC_SPINLOCK_UNLOCK(&IntETask(ThisTask
->tc_UnionETask
.tc_ETask
)->iet_TaskLock
);
86 /* Do those bits raise exceptions? */
87 if (task
->tc_SigRecvd
& task
->tc_SigExcept
)
89 /* Yes. Set the exception flag. */
90 task
->tc_Flags
|= TF_EXCEPT
;
92 D(bug("[Exec] Signal: TF_EXCEPT set\n"));
95 if the target task is running (called from within interrupt handler),
96 raise the exception or defer it for later.
98 if (task
->tc_State
== TS_RUN
)
100 D(bug("[Exec] Signal: signaling running task\n"));
101 #if defined(__AROSEXEC_SMP__)
102 if (IntETask(task
->tc_UnionETask
.tc_ETask
)->iet_CpuNumber
== cpunum
)
105 /* Order a reschedule */
107 #if defined(__AROSEXEC_SMP__)
111 D(bug("[Exec] Signal:\n"));
123 Is the task receiving the signals waiting on them
124 (or on a exception) ?
126 if ((task
->tc_State
== TS_WAIT
) &&
127 (task
->tc_SigRecvd
& (task
->tc_SigWait
| task
->tc_SigExcept
)))
129 D(bug("[Exec] Signal: signaling waiting task\n"));
131 /* Yes. Move it to the ready list. */
132 #if defined(__AROSEXEC_SMP__)
133 task_listlock
= &PrivExecBase(SysBase
)->TaskWaitSpinLock
;
134 EXEC_SPINLOCK_LOCK(task_listlock
, SPINLOCK_MODE_WRITE
);
137 Remove(&task
->tc_Node
);
138 task
->tc_State
= TS_READY
;
139 #if defined(__AROSEXEC_SMP__)
140 EXEC_SPINLOCK_UNLOCK(task_listlock
);
142 task_listlock
= EXEC_SPINLOCK_LOCK(&PrivExecBase(SysBase
)->TaskReadySpinLock
, SPINLOCK_MODE_WRITE
);
145 Enqueue(&SysBase
->TaskReady
, &task
->tc_Node
);
146 #if defined(__AROSEXEC_SMP__)
147 EXEC_SPINLOCK_UNLOCK(task_listlock
);
149 task_listlock
= NULL
;
151 /* Has it a higher priority as the current one? */
153 #if defined(__AROSEXEC_SMP__)
154 (IntETask(task
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
& KrnGetCPUMask(cpunum
)) &&
156 (task
->tc_Node
.ln_Pri
> ThisTask
->tc_Node
.ln_Pri
))
159 Yes. A taskswitch is necessary. Prepare one if possible.
160 (If the current task is not running it is already moved)
162 if (ThisTask
->tc_State
== TS_RUN
)
169 #if !defined(__AROSEXEC_SMP__)
173 D(bug("[Exec] Signal: 0x%p finished signal processing\n", task
));