Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!mips!apple!portal!cup.portal.com!phorgan From: phorgan@cup.portal.com (Patrick John Horgan) Newsgroups: comp.sys.amiga.programmer Subject: CreateTask Message-ID: <42890@cup.portal.com> Date: 2 Jun 91 06:36:54 GMT Organization: The Portal System (TM) Lines: 115 I couldn't post my original hack of CreateTask, since it was based on Manx's source, but I did another based on the one in the Revised and Updated Includes and Autodocs manual. The only difference between this and the one in the Includes and Autodocs is the memory is allocated for the name, and a copy is made of the name so that it will be reentrent. The one I sent to Manx actually added the string allocation to the one for the stack, to reduce fragmentation. ~~~~~~~~~~~~~~~~~cut here~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /*~~~~~ amiga.lib/CreateTask ~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #include #include #include #include #include /* The template for the mementries. Unfortunately, this is hard to do * from C; mementries have unions, and they cannot be statically * initialized... * * In the interest of simplicity I recreate the mem entry structures * here with appropriate sizes. We will copy this to a local variable * and set the stack size to what the user specified, then attempt * to actually allocate the memory. */ #define ME_TASK 0 #define ME_STACK 1 #define ME_STRING 2 #define NUMENTRIES 3 struct FakeMemEntry{ ULONG fme_Reqs; ULONG fme_Length; }; struct FakeMemList{ struct Node fml_Node; UWORD fml_NumEntries; struct FakeMemEntry fml_ME[NUMENTRIES]; } TaskMemTemplate = { { 0 }, /* node */ NUMENTRIES, /* numentries */ { /* Actual entries. */ { MEMF_PUBLIC | MEMF_CLEAR, sizeof(struct Task ) }, /* task */ { MEMF_CLEAR, 0 }, /* stack */ { MEMF_CLEAR, 0 } /* name */ } }; struct Task * CreateTask(const char *name,long pri,void *start_pc,long stksiz) { struct Task *newTask; struct FakeMemList fakememlist; struct MemList *ml; short namelen; /* Round up the stack size in longwords */ stksiz = (stksiz+3)&~3; namelen = (strlen(name) + 1 + 3)&~3; /* strlen + 1 for \0 rounded up */ /* This will allocate two chunks of memory: task of PUBLIC * stack of PRIVATE */ fakememlist = TaskMemTemplate; fakememlist.fml_ME[ME_STACK].fme_Length = stksiz; fakememlist.fml_ME[ME_STRING].fme_Length = namelen; ml = ( struct MemList *)AllocEntry((struct MemList *)&fakememlist); if(!ml) return(NULL); /* set the stack accounting stuff */ newTask = (struct Task *)ml->ml_ME[ME_TASK].me_Addr; newTask->tc_SPLower=ml->ml_ME[ME_STACK].me_Addr; newTask->tc_SPUpper=(APTR)((ULONG)(newTask->tc_SPLower)+stksiz); newTask->tc_SPReg =newTask->tc_SPUpper; /* Copy the string to our new memory */ strcpy((char *)ml->ml_ME[ME_STRING].me_Addr,name); /* misc task data structures */ newTask->tc_Node.ln_Type = NT_TASK; newTask->tc_Node.ln_Pri = pri; newTask->tc_Node.ln_Name = (char *)ml->ml_ME[ME_STRING].me_Addr; /* Add it to the tasks memory list */ NewList(&newTask->tc_MemEntry); AddHead(&newTask->tc_MemEntry,(struct Node *)ml); /* Add the task to the system -- use the default final PC */ AddTask(newTask, start_pc, 0L); return(newTask); } /*~~~~* amiga.lib/DeleteTask ~~~~~~~~~~~~~~~~~~~~~~~~~~*/ void DeleteTask(struct Task *tp) { /* Because we added a MemList structure to the task's TC_MEMENTRY * structure, all the memory will be freed up for us! */ RemTask( tp ); }