/* Task_Routines.c Copyright 1987 by James M Synge */ /* This file contains CreateTask() and DeleteTask(), * versions of the routines of the same names in the ROM * Kernel Manual. */ #include "exec/types.h" #include "exec/ports.h" #include "exec/tasks.h" #include "exec/memory.h" struct Task * CreateTask(Task_Name, Priority, Startup_Routine, Stack_Size) char *Task_Name; int Priority; void (* Startup_Routine) (); int Stack_Size; { /* A pointer to the child task's task structure. */ register struct Task *Child; register APTR Child_Stack; /* A pointer to it's stack */ register APTR AllocMem(); /* First allocate a stack for the task. */ Child_Stack = AllocMem(Stack_Size, MEMF_CLEAR); if (Child_Stack == 0) { /* Couldn't allocate a stack! And we cann't print an * error message because this routine could be called * by a task or a process which doesn't have a window. */ return(NULL); }; /* Now allocate a Task structure. */ Child = (struct Task *) AllocMem(sizeof(struct Task), MEMF_CLEAR | MEMF_PUBLIC); if (Child == NULL) { FreeMem(Child_Stack, Stack_Size); return(NULL); }; /* Now initialize the task structure as per the RKM. */ Child->tc_SPLower = Child_Stack; Child->tc_SPReg = Child->tc_SPUpper = (APTR)( (ULONG)Child_Stack + (ULONG)Stack_Size); Child->tc_Node.ln_Type = NT_TASK; Child->tc_Node.ln_Pri = Priority; Child->tc_Node.ln_Name = Task_Name; AddTask(Child, Startup_Routine, 0L); return(Child); } /* DeleteTask is written in a style which will allow it to * be called by any task, including the task being deleted. * Note that it can not delete an AmigaDOS Process. */ void DeleteTask(Child) register struct Task *Child; { register ULONG Stack_Size; if (Child == NULL) return; /* Free up the stack and the Task structure. This is * done inside a Forbid() / Permit() so that no other * task can do the same. */ Forbid(); if (Child->tc_Node.ln_Type != NT_TASK) { /* OOPS! It ain't a Task! */ Permit(); return; } Stack_Size = (ULONG)(Child->tc_SPUpper) - (ULONG)(Child->tc_SPLower); FreeMem(Child->tc_SPLower, Stack_Size); FreeMem(Child, sizeof(struct Task)); /* Now remove the task. This will not return if it is * removing the current task. */ RemTask( Child ); /* If we removed another task, then we continue on: * so call Permit() and return. */ Permit(); return; }