fix off-by-1 screen title fill
[AROS.git] / rom / exec / remtask.c
blobc0c125aaf831203d5a585d4465a1fba5727258b5
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Remove a task
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <exec/execbase.h>
11 #include <exec/tasks.h>
12 #include <aros/libcall.h>
13 #include <proto/exec.h>
14 #include <proto/kernel.h>
15 #include <aros/symbolsets.h>
17 #include "exec_intern.h"
18 #include "exec_util.h"
19 #include "exec_debug.h"
21 /*****************************************************************************
23 NAME */
25 AROS_LH1(void, RemTask,
27 /* SYNOPSIS */
28 AROS_LHA(struct Task *, task, A1),
30 /* LOCATION */
31 struct ExecBase *, SysBase, 48, Exec)
33 /* FUNCTION
34 Remove a task from the task lists. All memory in the tc_MemEntry list
35 is freed and a reschedule is done. It's safe to call RemTask() outside
36 Forbid() or Disable().
38 This function is one way to get rid of the current task. The other way
39 is to fall through the end of the entry point.
41 INPUTS
42 task - Task to be removed. NULL means current task.
44 RESULT
46 NOTES
48 EXAMPLE
50 BUGS
52 SEE ALSO
53 AddTask()
55 INTERNALS
57 ******************************************************************************/
59 AROS_LIBFUNC_INIT
61 struct MemList *mb;
62 struct ETask *et;
63 BOOL suicide;
65 /* A value of NULL means current task */
66 if (task==NULL)
67 task=SysBase->ThisTask;
69 DREMTASK("RemTask (0x%p (\"%s\"))", task, task->tc_Node.ln_Name);
71 /* Don't let any other task interfere with us at the moment
73 Forbid();
75 suicide = (task == SysBase->ThisTask);
76 if (suicide)
77 DREMTASK("Removing itself");
79 /* Remove() here, before freeing the MemEntry list. Because
80 the MemEntry list might contain the task struct itself! */
82 if (!suicide)
83 Remove(&task->tc_Node);
86 * The task is being removed.
87 * This is an important signal for Alert() which will not attempt to use
88 * the context which is being deleted, for example.
90 task->tc_State = TS_REMOVED;
92 /* Delete context */
93 et = GetETask(task);
94 if (et != NULL)
95 KrnDeleteContext(et->et_RegFrame);
97 /* Uninitialize ETask structure */
98 DREMTASK("Cleaning up ETask et=%p", et);
99 CleanupETask(task);
101 /* Freeing myself? */
102 if (suicide)
105 * Send task to task cleaner to clean up memory. This avoids ripping
106 * memory from underneath a running Task. Message is basically a
107 * Node, so we use our task's tc_Node as a message. We use
108 * InternalPutMsg() because it won't change ln_Type. Just in case...
110 DREMTASK("Sending to garbage man");
111 InternalPutMsg(((struct IntExecBase *)SysBase)->ServicePort,
112 (struct Message *)task, SysBase);
114 /* Changing the task lists always needs a Disable(). */
115 Disable();
118 Since I don't know how many levels of Forbid()
119 are already pending I set a default value.
121 SysBase->TDNestCnt = -1;
123 /* And force a task switch. Note: Dispatch, not Switch,
124 because the state of ThisTask must not be saved
127 KrnDispatch();
128 /* Does not return. */
130 else
133 * Free all memory in the tc_MemEntry list.
134 * We do this here because it's unsafe to send it to the service task:
135 * by the time the service task processes it, the task structure may
136 * have been freed following the return of this function.
138 while((mb = (struct MemList *) RemHead(&task->tc_MemEntry)) != NULL)
139 FreeEntry(mb);
142 /* All done. */
143 Permit();
145 DREMTASK("Success");
147 AROS_LIBFUNC_EXIT