r4684@vps: verhaegs | 2007-05-04 21:04:10 -0400
[AROS.git] / rom / exec / dispatch.c
blob0bb9c40c5ed3ca59f40d077f33dad7ceccf3b131
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Dispatch() - Tell the system that we have switched tasks.
6 Lang: english
7 */
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***********************************************************************
20 NAME */
21 #include <proto/exec.h>
23 AROS_LH0(void, Dispatch,
25 /* LOCATION */
26 struct ExecBase *, SysBase, 10, Exec)
28 /* FUNCTION
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
32 switched.
34 The tc_Switch and tc_Launch functions will be called with
35 SysBase in register A6.
37 INPUTS
38 None.
40 RESULT
41 The current task will have changed.
43 NOTES
45 EXAMPLE
47 BUGS
48 Not a good function to call.
50 SEE ALSO
51 Switch(), Reschedule()
53 INTERNALS
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 ******************************************************************************/
60 AROS_LIBFUNC_INIT
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 )
100 /* POW! */
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++;
113 else
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
127 can't be delivered.
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
133 get to here.
135 SysBase->IdleCount++;
139 /* Aha, the task pointed to be SysBase->ThisTask is correct. */
141 AROS_LIBFUNC_EXIT
142 } /* Dispatch() */