Test current SDI headers.
[AROS.git] / rom / exec / signal.c
blob726faf84d588d2c4ac33ff565e6e38ca62eab2e4
1 /*
2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Send some signal to a given task
6 Lang: english
7 */
8 #define DEBUG 0
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>
18 #include "etask.h"
19 #endif
21 /*****************************************************************************
23 NAME */
25 AROS_LH2(void, Signal,
27 /* SYNOPSIS */
28 AROS_LHA(struct Task *, task, A1),
29 AROS_LHA(ULONG, signalSet, D0),
31 /* LOCATION */
32 struct ExecBase *, SysBase, 54, Exec)
34 /* FUNCTION
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.
39 INPUTS
40 task - Pointer to task structure.
41 signalSet - The set of signals to send to the task.
43 RESULT
45 NOTES
46 This function may be used from interrupts.
48 EXAMPLE
50 BUGS
52 SEE ALSO
53 AllocSignal(), FreeSignal(), Wait(), SetSignal(), SetExcept()
55 INTERNALS
57 HISTORY
59 ******************************************************************************/
61 AROS_LIBFUNC_INIT
63 struct Task *ThisTask = GET_THIS_TASK;
64 #if defined(__AROSEXEC_SMP__)
65 spinlock_t *task_listlock = NULL;
66 int cpunum = KrnGetCPUNumber();
67 #endif
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(task->tc_UnionETask.tc_ETask)->iet_TaskLock, SPINLOCK_MODE_WRITE);
77 #endif
78 Disable();
79 /* Set the signals in the task structure. */
80 task->tc_SigRecvd |= signalSet;
81 #if defined(__AROSEXEC_SMP__)
82 EXEC_SPINLOCK_UNLOCK(&IntETask(task->tc_UnionETask.tc_ETask)->iet_TaskLock);
83 Enable();
84 #endif
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");)
94 /*
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)
104 #endif
105 /* Order a reschedule */
106 Reschedule();
107 #if defined(__AROSEXEC_SMP__)
109 else
111 D(bug("[Exec] Signal:\n");)
113 #else
114 Enable();
115 #endif
117 /* All done. */
118 return;
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);
135 Forbid();
136 #endif
137 Remove(&task->tc_Node);
138 task->tc_State = TS_READY;
139 #if defined(__AROSEXEC_SMP__)
140 EXEC_SPINLOCK_UNLOCK(task_listlock);
141 Permit();
142 task_listlock = EXEC_SPINLOCK_LOCK(&PrivExecBase(SysBase)->TaskReadySpinLock, SPINLOCK_MODE_WRITE);
143 Forbid();
144 #endif
145 Enqueue(&SysBase->TaskReady, &task->tc_Node);
146 #if defined(__AROSEXEC_SMP__)
147 EXEC_SPINLOCK_UNLOCK(task_listlock);
148 Permit();
149 task_listlock = NULL;
150 #endif
151 /* Has it a higher priority as the current one? */
152 if (
153 #if defined(__AROSEXEC_SMP__)
154 (IntETask(task->tc_UnionETask.tc_ETask)->iet_CpuAffinity & KrnGetCPUMask(cpunum)) &&
155 #endif
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)
164 Reschedule();
169 #if !defined(__AROSEXEC_SMP__)
170 Enable();
171 #endif
173 D(bug("[Exec] Signal: 0x%p finished signal processing\n", task);)
175 AROS_LIBFUNC_EXIT