r4684@vps: verhaegs | 2007-05-04 21:04:10 -0400
[AROS.git] / rom / exec / exec_util.c
blobb61ba9d42278326e353c56939c23a5aed051e399
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Exec utility functions.
6 Lang: english
7 */
8 #include <exec/lists.h>
9 #include <exec/tasks.h>
10 #include <exec/memory.h>
11 #include <exec/execbase.h>
13 #include <proto/exec.h>
15 #include "etask.h"
16 #include "exec_util.h"
18 /*****************************************************************************
20 NAME */
21 #include "exec_util.h"
23 APTR Exec_AllocTaskMem (
25 /* SYNOPSIS */
26 struct Task * task,
27 ULONG size,
28 ULONG req,
29 struct ExecBase *SysBase)
31 /* FUNCTION
32 Allocate memory which will be freed when the task is removed.
34 INPUTS
35 task - The memory will be freed when this task is removed.
36 size - How much memory.
37 req - What memory. See AllocMem() for details.
39 RESULT
40 Adress to a memory block or NULL if no memory was available.
42 NOTES
44 EXAMPLE
46 BUGS
48 SEE ALSO
49 AllocMem(), FreeTaskMem()
51 INTERNALS
52 The memory is allocated and queued in the tc_MemList. This
53 list is freed in RemTask().
55 ******************************************************************************/
57 struct MemList * ml;
58 APTR mem;
60 ml = AllocMem (sizeof (struct MemList), MEMF_ANY);
61 mem = AllocMem (size, req);
63 if (!ml || !mem)
65 if (ml)
66 FreeMem (ml, sizeof (struct MemList));
68 if (mem)
69 FreeMem (mem, size);
71 return NULL;
74 ml->ml_NumEntries = 1;
75 ml->ml_ME[0].me_Addr = mem;
76 ml->ml_ME[0].me_Length = size;
78 Forbid ();
79 AddHead (&task->tc_MemEntry, &ml->ml_Node);
80 Permit ();
82 return mem;
83 } /* AllocTaskMem */
86 /*****************************************************************************
88 NAME */
89 #include "exec_util.h"
91 void Exec_FreeTaskMem (
93 /* SYNOPSIS */
94 struct Task * task,
95 APTR mem,
96 struct ExecBase *SysBase)
98 /* FUNCTION
99 Freeate memory which will be freed when the task is removed.
101 INPUTS
102 task - The memory will be freed when this task is removed.
103 size - How much memory.
104 req - What memory. See FreeMem() for details.
106 RESULT
107 Adress to a memory block or NULL if no memory was available.
109 NOTES
111 EXAMPLE
113 BUGS
115 SEE ALSO
116 FreeMem(), FreeTaskMem()
118 INTERNALS
119 The memory is allocated and queued in the tc_MemList. This
120 list is freed in RemTask().
122 ******************************************************************************/
124 struct MemList * ml, * next;
126 Forbid ();
128 ForeachNodeSafe (&task->tc_MemEntry, ml, next)
131 Quick check: If the node was allocated by AllocTaskMem(),
132 then it has only one entry.
134 if (ml->ml_NumEntries == 1
135 && ml->ml_ME[0].me_Addr == mem
138 Remove (&ml->ml_Node);
139 Permit ();
141 FreeMem (ml->ml_ME[0].me_Addr, ml->ml_ME[0].me_Length);
142 FreeMem (ml, sizeof (struct MemList));
144 return;
148 Permit ();
150 } /* FreeTaskMem */
152 /*****************************************************************************
154 NAME */
155 #include "exec_util.h"
157 struct Task * Exec_FindTaskByID(
159 /* SYNOPSIS */
160 ULONG id,
161 struct ExecBase *SysBase)
163 /* FUNCTION
164 Scan through the task lists searching for the task whose
165 et_UniqueID field matches.
167 INPUTS
168 id - The task ID to match.
170 RESULT
171 Address of the Task control structure that matches, or
172 NULL otherwise.
174 NOTES
176 EXAMPLE
178 BUGS
180 SEE ALSO
182 INTERNALS
184 ******************************************************************************/
186 struct Task *t;
187 struct ETask *et;
190 First up, check ThisTask. It could be NULL because of exec_init.c
192 if (SysBase->ThisTask != NULL)
194 et = GetETask(SysBase->ThisTask);
195 if (et != NULL && et->et_UniqueID == id)
196 return SysBase->ThisTask;
199 /* Next, go through the ready list */
200 ForeachNode(&SysBase->TaskReady, t)
202 et = GetETask(t);
203 if (et != NULL && et->et_UniqueID == id)
204 return t;
207 /* Finally, go through the wait list */
208 ForeachNode(&SysBase->TaskWait, t)
210 et = GetETask(t);
211 if (et != NULL && et->et_UniqueID == id)
212 return t;
215 return NULL;
218 /*****************************************************************************
220 NAME */
221 #include "exec_util.h"
223 struct ETask * Exec_FindChild(
225 /* SYNOPSIS */
226 ULONG id,
227 struct ExecBase *SysBase)
229 /* FUNCTION
230 Scan through the current tasks children list searching for the task
231 whose et_UniqueID field matches.
233 INPUTS
234 id - The task ID to match.
236 RESULT
237 Address of the ETask structure that matches, or
238 NULL otherwise.
240 NOTES
242 EXAMPLE
244 BUGS
246 SEE ALSO
248 INTERNALS
250 ******************************************************************************/
252 struct ETask *et;
253 struct ETask *thisET;
255 thisET = GetETask(FindTask(NULL));
256 if (thisET != NULL)
258 ForeachNode (&thisET->et_Children, et)
260 if (et->et_UniqueID == id)
261 return et;
264 return NULL;
267 void
268 Exec_InitETask(struct Task *task, struct ETask *et, struct ExecBase *SysBase)
270 et->et_Parent = FindTask(NULL);
271 NEWLIST(&et->et_Children);
273 /* Initialise the message list */
274 NEWLIST(&et->et_TaskMsgPort.mp_MsgList);
275 et->et_TaskMsgPort.mp_Flags = PA_SIGNAL;
276 et->et_TaskMsgPort.mp_Node.ln_Type = NT_MSGPORT;
277 et->et_TaskMsgPort.mp_SigTask = task;
278 et->et_TaskMsgPort.mp_SigBit = SIGB_CHILD;
280 /* Initialise the trap fields */
281 et->et_TrapAlloc = SysBase->TaskTrapAlloc;
282 et->et_TrapAble = 0;
284 #ifdef DEBUG_ETASK
286 int len = strlen(task->tc_Node.ln_Name) + 1;
287 IntETask(et)->iet_Me = AllocVec(len, MEMF_CLEAR|MEMF_PUBLIC);
288 if (IntETask(et)->iet_Me != NULL)
289 CopyMem(task->tc_Node.ln_Name, IntETask(et)->iet_Me, len);
291 #endif
293 #if 1
294 Forbid();
295 while(et->et_UniqueID == 0)
298 * Add some fuzz on wrapping. Its likely that the early numbers
299 * where taken by somebody else.
301 if(++SysBase->ex_TaskID == 0)
302 SysBase->ex_TaskID = 1024;
304 Disable();
305 if(Exec_FindTaskByID(SysBase->ex_TaskID, SysBase) == NULL)
306 et->et_UniqueID = SysBase->ex_TaskID;
307 Enable();
309 Permit();
310 #endif