revert between 56095 -> 55830 in arch
[AROS.git] / rom / exec / service.c
blob82daaa15ab712f981436af0ff1f2aaf73e416c36
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: exec.library's internal service task. Performs memory management according
6 to task scheduler's requests.
7 Lang: english
8 */
10 #include <exec/execbase.h>
11 #include <exec/tasks.h>
12 #include <aros/libcall.h>
13 #include <proto/exec.h>
15 #include "exec_intern.h"
16 #include "exec_util.h"
17 #include "exec_debug.h"
19 void ServiceTask(struct ExecBase *SysBase)
21 #if defined(__AROSEXEC_SMP__)
22 struct Task *serviceTask;
23 #endif
24 struct Task *task;
25 struct MemList *mb, *mbnext;
26 BOOL taskRequeue;
27 DINIT("ServiceTask: Started up");
29 #if defined(__AROSEXEC_SMP__)
30 serviceTask = FindTask(NULL);
31 DINIT("ServiceTask: task @ 0x%p", serviceTask);
32 #endif
35 { /* forever */
38 while ((task = (struct Task *)GetMsg(PrivExecBase(SysBase)->ServicePort)))
40 DREMTASK("ServiceTask: Request for Task 0x%p, State %08X\n", task, task->tc_State);
41 taskRequeue = TRUE;
44 * If we ever need to use TSS here, we'll need to explicitly check its size here.
45 * However we don't need this, because we never call so high-level libraries.
46 * So, currently we ignore this.
49 switch (task->tc_State)
51 #if defined(__AROSEXEC_SMP__)
52 case TS_TOMBSTONED:
53 if (!(PrivExecBase(SysBase)->IntFlags & EXECF_CPUAffinity) || (GetIntETask(serviceTask)->iet_CpuNumber== (IPTR)task->tc_UserData))
55 DREMTASK("ServiceTask: Task is running on this CPU (%03u)\n", task->tc_UserData);
56 taskRequeue = FALSE;
58 #endif
59 case TS_REMOVED:
60 if (taskRequeue)
62 DREMTASK("ServiceTask: Requeueing request for Task 0x%p <%s> (State:%08x)", task, task->tc_Node.ln_Name, task->tc_State);
63 InternalPutMsg(PrivExecBase(SysBase)->ServicePort,
64 (struct Message *)task, SysBase);
65 break;
67 case TS_INVALID:
68 DREMTASK("ServiceTask: Removal request for Task 0x%p <%s> (State:%08x)", task, task->tc_Node.ln_Name, task->tc_State);
70 // TODO: Make sure the task has terminated..
71 task->tc_State = TS_INVALID;
74 * Note tc_MemEntry list is part of the task structure which
75 * usually is also placed in tc_MemEntry. MungWall_Check()
76 * will fill freed memory and destroy our list while we are
77 * iterating or the freed memory including our list could be
78 * reused by some other task. We take special care of this by
79 * resetting ln_Succ of the last node to NULL. This way we
80 * avoid getting back to our List structure.
82 task->tc_MemEntry.lh_TailPred->ln_Succ = NULL;
84 for (mb = (struct MemList *)task->tc_MemEntry.lh_Head; mb; mb = mbnext)
86 /* Free one MemList node */
87 mbnext = (struct MemList *)mb->ml_Node.ln_Succ;
89 DREMTASK("ServiceTask: Freeing MemList 0x%p", mb);
90 FreeEntry(mb);
92 break;
94 default:
95 if ((task->tc_Node.ln_Type == NT_TASK) || (task->tc_Node.ln_Type == NT_PROCESS))
97 /* FIXME: Add fault handling here. Perhaps kernel-level GURU. */
98 DREMTASK("ServiceTask: Task 0x%p <%s> not in servicable state!\n", task, task->tc_Node.ln_Name);
99 DREMTASK("ServiceTask: State = %08X\n", task->tc_State);
102 * Mark the task as ready to run again. Move it back to TaskReady list.
104 #if !defined(EXEC_REMTASK_NEEDSSWITCH)
105 task->tc_State = TS_READY;
106 Enqueue(&SysBase->TaskReady, &task->tc_Node);
107 #else
108 krnSysCallReschedTask(task, TS_READY);
109 #endif
111 else
113 DREMTASK("ServiceTask: Called with something that is not a task??\n");
115 break;
119 WaitPort(PrivExecBase(SysBase)->ServicePort);
120 } while(1);