2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Dispatch() - Tell the system that we have switched tasks.
9 #include <exec/types.h>
10 #include <exec/lists.h>
11 #include <exec/tasks.h>
12 #include <exec/execbase.h>
13 #include <exec/alerts.h>
15 #include <proto/arossupport.h>
16 #include <aros/asmcall.h>
18 /*****i***********************************************************************
21 #include <proto/exec.h>
23 AROS_LH0(void, Dispatch
,
26 struct ExecBase
*, SysBase
, 10, Exec
)
29 Inform SysBase that the task has been switched. This function
30 only does all the non-system-dependant dispatching. It is up
31 to the implementation to unsure that the tasks do actually get
34 The tc_Switch and tc_Launch functions will be called with
35 SysBase in register A6.
41 The current task will have changed.
48 Not a good function to call.
51 Switch(), Reschedule()
54 You can use your CPU dependant function as a wrapper around this
55 function if you want. But you have to make sure then that you
56 do NOT call Dispatch() from the exec.library function table.
58 ******************************************************************************/
62 struct Task
*this, *task
;
64 this = SysBase
->ThisTask
;
66 /* Check the stack... */
68 /* Get the task which is ready to run */
69 if(( task
= (struct Task
*)RemHead(&SysBase
->TaskReady
)))
71 if(this->tc_Flags
& TF_SWITCH
)
73 AROS_UFC1(void, this->tc_Switch
,
74 AROS_UFCA(struct ExecBase
*, SysBase
, A6
));
77 this->tc_TDNestCnt
= SysBase
->TDNestCnt
;
78 this->tc_IDNestCnt
= SysBase
->IDNestCnt
;
80 /* Oh dear, the previous task has just vanished...
81 you should have called Switch() instead :-)
83 We don't change the state of the old task, otherwise it
84 may never get freed.(See RemTask() for details).
86 We especially don't add it to the ReadyList !
88 task
->tc_State
= TS_RUN
;
90 SysBase
->TDNestCnt
= task
->tc_TDNestCnt
;
91 SysBase
->IDNestCnt
= task
->tc_IDNestCnt
;
93 SysBase
->ThisTask
= task
;
95 /* Check the stack of the task we are about to launch */
97 if( task
->tc_SPReg
<= task
->tc_SPLower
98 || task
->tc_SPReg
>= task
->tc_SPUpper
)
101 Alert(AT_DeadEnd
|AN_StackProbe
);
104 if(task
->tc_Flags
& TF_LAUNCH
)
106 AROS_UFC1(void, task
->tc_Launch
,
107 AROS_UFCA(struct ExecBase
*, SysBase
, A6
));
110 /* Increase the dispatched counter */
111 SysBase
->DispCount
++;
115 kprintf("Eh? No tasks left to Dispatch()\n");
118 We have reached a point where there are no ready tasks.
119 What can you do? Well you can basically go into some kind of
120 loop that can be interrupted easily. If you do this however
121 you must re-enable interrupts.
123 If you seem to go into endless loops with nothing happening,
124 it could be that you have not enabled interrupts, or alternatively
125 you could be running under emulation, disabled all signals and be
126 getting some kind of process error (SIGBUS, SIGSEGV etc), which
129 If you do go idle, increase the counter please.
131 You could also create a task (the idle task), which basically
132 does nothing, and switch to that, in which case you should never
135 SysBase->IdleCount++;
139 /* Aha, the task pointed to be SysBase->ThisTask is correct. */