revert between 56095 -> 55830 in arch
[AROS.git] / rom / exec / remtask.c
blob720fbae0e76f8259246c1f0cc705ebe800560fd3
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Remove a task
6 Lang: english
7 */
9 #include <exec/execbase.h>
10 #include <exec/tasks.h>
11 #include <aros/libcall.h>
12 #include <proto/exec.h>
13 #include <aros/symbolsets.h>
15 #include "etask.h"
16 #include "exec_intern.h"
17 #include "exec_util.h"
18 #include "exec_debug.h"
20 /*****************************************************************************
22 NAME */
24 AROS_LH1(void, RemTask,
26 /* SYNOPSIS */
27 AROS_LHA(struct Task *, task, A1),
29 /* LOCATION */
30 struct ExecBase *, SysBase, 48, Exec)
32 /* FUNCTION
33 Remove a task from the task lists. All memory in the tc_MemEntry list
34 is freed and a reschedule is done. It's safe to call RemTask() outside
35 Forbid() or Disable().
37 This function is one way to get rid of the current task. The other way
38 is to fall through the end of the entry point.
40 INPUTS
41 task - Task to be removed. NULL means current task.
43 RESULT
45 NOTES
47 EXAMPLE
49 BUGS
51 SEE ALSO
52 AddTask()
54 INTERNALS
56 ******************************************************************************/
58 AROS_LIBFUNC_INIT
60 struct MemList *mb;
61 struct ETask *et;
62 struct Task *suicide = GET_THIS_TASK;
64 /* A value of NULL means current task */
65 if (task == NULL)
66 task = suicide;
68 DREMTASK("RemTask (0x%p (\"%s\"))", task, task->tc_Node.ln_Name);
70 /* Don't let any other task interfere with us at the moment */
71 Forbid();
73 /* Dont try to kill a dying task .. */
74 if ((task->tc_State != TS_INVALID) &&
75 (task->tc_State != TS_TOMBSTONED) &&
76 (task->tc_State != TS_REMOVED))
79 * The task is being removed.
80 * This is an important signal for Alert() which will not attempt to use
81 * the context which is being deleted, for example.
84 if (suicide == task)
86 DREMTASK("Removing itself");
87 task->tc_State = TS_REMOVED;
88 #if defined(EXEC_REMTASK_NEEDSSWITCH)
89 // make the scheduler detach us...
90 krnSysCallSwitch();
91 #endif
93 else
96 * Remove() here, before freeing the MemEntry list. Because
97 * the MemEntry list might contain the task struct itself!
99 #if !defined(EXEC_REMTASK_NEEDSSWITCH)
100 task->tc_State = TS_REMOVED;
101 Remove(&task->tc_Node);
102 #else
103 krnSysCallReschedTask(task, TS_REMOVED);
104 #endif
107 /* Delete context */
108 et = GetETask(task);
109 if (et != NULL)
111 #if defined(__AROSEXEC_SMP__)
112 // We must cache the CPU number here for the Exec Service Task...
113 task->tc_UserData = (APTR)IntETask(et)->iet_CpuNumber;
114 #endif
115 KrnDeleteContext(et->et_RegFrame);
118 /* Uninitialize ETask structure */
119 DREMTASK("Cleaning up ETask et=%p", et);
120 CleanupETask(task);
122 /* Freeing itself? */
123 if (suicide == task)
126 * Send task to task cleaner to clean up memory. This avoids ripping
127 * memory from underneath a running Task. Message is basically a
128 * Node, so we use our task's tc_Node as a message. We use
129 * InternalPutMsg() because it won't change ln_Type. Just in case...
131 DREMTASK("Sending to Exec service task");
132 InternalPutMsg(PrivExecBase(SysBase)->ServicePort,
133 (struct Message *)task, SysBase);
135 DREMTASK("Disabling interrupts");
136 /* Changing the task lists always needs a Disable(). */
137 Disable();
139 DREMTASK("And multitasking..");
141 * We don't know how many levels of Forbid()
142 * are already pending, so use a default value.
144 TDNESTCOUNT_SET(-1);
147 * Force rescheduling.
148 * Note #1: We dont want to preseve the task context so use Dispatch, not Switch.
149 * Note #2: We will never return from the dispatch to "ThisTask"
152 DREMTASK("Switching away..");
153 /* It is no longer a valid task.. */
154 task->tc_State = TS_INVALID;
155 KrnDispatch();
157 else
160 * Free all memory in the tc_MemEntry list.
161 * We do this here because it's unsafe to send it to the service task:
162 * by the time the service task processes it, the task structure may
163 * have been freed following the return of this function.
165 while((mb = (struct MemList *) RemHead(&task->tc_MemEntry)) != NULL)
166 FreeEntry(mb);
170 /* All done. */
171 Permit();
173 DREMTASK("Success");
175 AROS_LIBFUNC_EXIT