2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
5 Desc: Send some signal to a given task
9 #include <exec/execbase.h>
10 #include <aros/libcall.h>
11 #include <proto/exec.h>
12 #include <aros/debug.h>
14 #include "exec_intern.h"
16 /*****************************************************************************
20 AROS_LH2(void, Signal
,
23 AROS_LHA(struct Task
*, task
, A1
),
24 AROS_LHA(ULONG
, signalSet
, D0
),
27 struct ExecBase
*, SysBase
, 54, Exec
)
30 Send some signals to a given task. If the task is currently waiting
31 on these signals, has a higher priority as the current one and if
32 taskswitches are allowed the new task begins to run immediately.
35 task - Pointer to task structure.
36 signalSet - The set of signals to send to the task.
41 This function may be used from interrupts.
48 AllocSignal(), FreeSignal(), Wait(), SetSignal(), SetExcept()
54 ******************************************************************************/
58 #if defined(__AROSEXEC_SMP__)
59 spinlock_t
*task_listlock
= NULL
;
62 /* Protect the task lists against other tasks that may use Signal(). */
63 #if defined(__AROSEXEC_SMP__)
64 switch (task
->tc_State
)
67 task_listlock
=&PrivExecBase(SysBase
)->TaskRunningSpinLock
;
70 task_listlock
= &PrivExecBase(SysBase
)->TaskWaitSpinLock
;
73 task_listlock
= &PrivExecBase(SysBase
)->TaskReadySpinLock
;
76 EXEC_SPINLOCK_LOCK(task_listlock
, SPINLOCK_MODE_WRITE
);
80 /* Set the signals in the task structure. */
81 task
->tc_SigRecvd
|= signalSet
;
83 /* Do those bits raise exceptions? */
84 if (task
->tc_SigExcept
& task
->tc_SigRecvd
)
86 /* Yes. Set the exception flag. */
87 task
->tc_Flags
|= TF_EXCEPT
;
89 /* task is running (Signal() called from within interrupt)? Raise the exception or defer it for later. */
90 if (task
->tc_State
== TS_RUN
)
92 #if defined(__AROSEXEC_SMP__)
93 EXEC_SPINLOCK_UNLOCK(task_listlock
);
95 /* Order a reschedule */
106 Is the task receiving the signals waiting on them
107 (or on a exception) ?
109 if ((task
->tc_State
== TS_WAIT
) &&
110 (task
->tc_SigRecvd
&(task
->tc_SigWait
| task
->tc_SigExcept
)))
112 /* Yes. Move him to the ready list. */
113 task
->tc_State
= TS_READY
;
114 Remove(&task
->tc_Node
);
115 #if defined(__AROSEXEC_SMP__)
116 EXEC_SPINLOCK_UNLOCK(task_listlock
);
118 task_listlock
= EXEC_SPINLOCK_LOCK(&PrivExecBase(SysBase
)->TaskReadySpinLock
, SPINLOCK_MODE_WRITE
);
121 Enqueue(&SysBase
->TaskReady
, &task
->tc_Node
);
123 /* Has it a higher priority as the current one? */
124 if (task
->tc_Node
.ln_Pri
> GET_THIS_TASK
->tc_Node
.ln_Pri
)
127 Yes. A taskswitch is necessary. Prepare one if possible.
128 (If the current task is not running it is already moved)
130 if (GET_THIS_TASK
->tc_State
== TS_RUN
)
132 #if defined(__AROSEXEC_SMP__)
133 EXEC_SPINLOCK_UNLOCK(task_listlock
);
134 task_listlock
= NULL
;
141 #if defined(__AROSEXEC_SMP__)
144 EXEC_SPINLOCK_UNLOCK(task_listlock
);