move VMWare SVGA driver to generic location
[AROS.git] / rom / exec / remtask.c
blob93606aaea04a8affca04793810db0b0b7a94f483
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Remove a task
6 Lang: english
7 */
8 #include <exec/execbase.h>
9 #include <exec/tasks.h>
10 #include <aros/libcall.h>
11 #include <proto/exec.h>
13 #include "exec_debug.h"
14 #ifndef DEBUG_RemTask
15 # define DEBUG_RemTask 0
16 #endif
17 #undef DEBUG
18 #if DEBUG_RemTask
19 # define DEBUG 1
20 #endif
21 #include <aros/debug.h>
23 /*****************************************************************************
25 NAME */
27 AROS_LH1(void, RemTask,
29 /* SYNOPSIS */
30 AROS_LHA(struct Task *, task, A1),
32 /* LOCATION */
33 struct ExecBase *, SysBase, 48, Exec)
35 /* FUNCTION
36 Remove a task from the task lists. All memory in the tc_MemEntry list
37 is freed and a rescedule is done. It's safe to call RemTask() out
38 of Forbid() or Disable().
39 This function is one way to get rid of the current task. The other way
40 is to fall through the end of the entry point.
42 INPUTS
43 task - Task to be removed. NULL means current task.
45 RESULT
47 NOTES
49 EXAMPLE
51 BUGS
53 SEE ALSO
54 AddTask()
56 INTERNALS
58 ******************************************************************************/
60 AROS_LIBFUNC_INIT
61 struct MemList *mb;
62 struct ETask *et;
64 /* A value of NULL means current task */
65 if (task==NULL)
66 task=SysBase->ThisTask;
68 D(bug("Call RemTask (%08lx (\"%s\"))\n", task, task->tc_Node.ln_Name));
69 et = GetETask(task);
72 Since it's possible that the following will free a task
73 structure that is used for some time afterwards it's
74 necessary to protect the free memory list so that nobody
75 can allocate that memory.
77 Forbid();
79 /* Remove() here, before freeing the MemEntry list. Because
80 the MemEntry list might contain the task struct itself! */
82 if(task != SysBase->ThisTask)
84 /* disable interrupts when changing the task lists */
85 Disable();
86 Remove(&task->tc_Node);
87 Enable();
89 /* force the task into the removed state, otherwise a received signal
90 * can bring it back to life */
91 task->tc_State = TS_REMOVED;
94 /* Free all memory in the tc_MemEntry list. */
95 while((mb=(struct MemList *)RemHead(&task->tc_MemEntry))!=NULL)
96 /* Free one MemList node */
97 FreeEntry(mb);
99 #if 0
100 if(et != NULL)
102 struct ETask *child;
104 /* Clean up after all the children that the task didn't do itself. */
105 ForeachNode(&et->et_TaskMsgPort.mp_MsgList, child)
107 /* This is effectively ChildFree() */
108 if(child->et_Result2)
109 FreeVec(child->et_Result2);
110 FreeVec(child);
113 /* Orphan all our remaining children. */
115 struct Task *save;
117 /* Do an effective ChildOrphan(0) */
118 ForeachNode(et->et_Children, child)
119 child->et_Parent = NULL;
122 /* If we have an ETask parent, tell it we have exited. */
123 if(et->et_Parent != NULL)
125 child = GetETask(et->et_Parent);
126 if(child != NULL)
127 PutMsg(&child->et_TaskMsgPort, et);
128 else
129 FreeVec(et);
131 else
132 FreeVec(et);
134 #else
135 if(et != NULL)
137 /* Orphan all our remaining children. */
138 struct ETask *child;
140 /* Do an effective ChildOrphan(0) */
141 #warning FIXME: should we link the children to our parent?
142 ForeachNode(&et->et_Children, child)
143 child->et_Parent = NULL;
145 /* If we have an ETask parent, unlink us from it */
146 if(et->et_Parent != NULL)
148 REMOVE(et);
151 FreeVec(et);
153 #endif
155 /* Changing the task lists always needs a Disable(). */
156 Disable();
158 /* Freeing myself? */
159 if(task==SysBase->ThisTask)
161 /* Can't do that - let the dispatcher do it. */
162 task->tc_State=TS_REMOVED;
165 Since I don't know how many levels of Forbid()
166 are already pending I set a default value.
168 SysBase->TDNestCnt=-1;
170 /* And force a task switch */
171 Switch();
172 /* Does not return. */
175 /* All done. */
176 Enable();
177 Permit();
179 ReturnVoid ("RemTask");
180 AROS_LIBFUNC_EXIT
181 } /* RemTask() */