dylan@june.cs.washington.edu (Dylan McNamee) (04/29/91)
I can't get CreateTask() to work correctly. I am adding a simple task, which does show up on the task list, but always waiting. Same thing happens when I try compiling Carolyn's sample CreateTask code. I am compiling with SAS 5.10a, -v option (no stack checking, as Carolyn suggests). What gives? thanks, -- dylan mcnamee / "Ten Years After WWIV...there wasn't much to do; dylan@cs.washington.edu \/all the bowling alleys were wrecked, so I spent most of my time looking for beer" from Strange Brew
jap@convex.cl.msu.edu (Joe Porkka) (04/29/91)
dylan@june.cs.washington.edu (Dylan McNamee) writes: >I can't get CreateTask() to work correctly. I am adding a simple task, >which does show up on the task list, but always waiting. Same thing happens >when I try compiling Carolyn's sample CreateTask code. >I am compiling with SAS 5.10a, -v option (no stack checking, as Carolyn >suggests). What gives? Maybe its waiting for a WorkBench Message??
f_j_reichert@saarag.zer.sub.org (05/02/91)
DYLAN%JUNE.CS.WASHINGTON.EDU@BUCHONIA.ZER wrote: #I can't get CreateTask() to work correctly. I am adding a simple task, #which does show up on the task list, but always waiting. Same thing happens #when I try compiling Carolyn's sample CreateTask code. subTaskRtn needs to reference some data, which is actually done as <offset>(a4) by default (was different when the example was released on fish-disks). So a4 needs to contain the global database when entering subTaskRtn. Simple Job, use lc -v -y -Lcnd task or lc -v -b0 -Lcnd task or change the source as follows: 19: <extern VOID subTaskRtn(); >extern VOID __saveds subTaskRtn(); 106:<VOID subTaskRtn() >VOID __saveds subTaskRtn() Best regards, F.J.Reichert ...{uunet}!cbmvax!cbmehq!cbmger!kbsaar!fjrei
phorgan@cup.portal.com (Patrick John Horgan) (06/02/91)
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 <exec/types.h> #include <exec/tasks.h> #include <exec/memory.h> #include <string.h> #include <functions.h> /* 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 ); }
Jeff_Petkau@tptbbs.UUCP (Jeff Petkau) (06/05/91)
In a message dated Mon 03 Jun 91 05:00, Phorgan@cup.portal.com (Patrick John Horgan) wrote: PH> I couldn't post my original hack of CreateTask, since it was based on PH> Manx's source, but I did another based on the one in the Revised and PH> Updated Includes and Autodocs manual. The only difference between this PH> and the one in the Includes and Autodocs is the memory is allocated for PH> the name, and a copy is made of the name so that it will be reentrent. ... PH> ml = (struct MemList *)AllocEntry((struct MemList *)&fakememlist); PH> if(!ml) PH> return(NULL); This is something I've been wondering about for a while now. In the 1.3 Includes & AutoDocs, it says of AllocEntry: "If enough memory cannot be obtained, then the requirements of the allocation that failed is returned and bit 31 is set." In other words, AllocEntry does _not_ return NULL on failure, and any code that assumes it does is in ghastly trouble when memory gets low. But in 1.3 Libraries & Devices, and in all the compiler libraries I've bothered to look at, CreateTask() does this very thing. So: is AllocEntry() misdocumented (after all, the documented behaviour is pretty damned silly), or has CreateTask() been broken in every single OS release to date, or am I just very confused, or what? -- Via DLG Pro v0.975b BONKBONKBONKBON I mean, the whole purpose of my existence is to O Jeff Petkau K serve you with hot buttered scrummy toast. N BONKBONK if you don't want any then my existence is K petkau@tptbbs.UUCP N meaningless. I toast, therefore I am. BONKBONKBONKBONKBONKBO - The toaster on Red Dwarf
ewout@topcat.commodore.com (Ewout Walraven) (06/05/91)
Jeff_Petkau@tptbbs.UUCP (Jeff Petkau) writes: >This is something I've been wondering about for a while now. In the 1.3 >Includes & AutoDocs, it says of AllocEntry: "If enough memory cannot be >obtained, then the requirements of the allocation that failed is returned and >bit 31 is set." In other words, AllocEntry does _not_ return NULL on >failure, and any code that assumes it does is in ghastly trouble when memory >gets low. But in 1.3 Libraries & Devices, and in all the compiler libraries >I've bothered to look at, CreateTask() does this very thing. So: is >AllocEntry() misdocumented (after all, the documented behaviour is pretty >damned silly), or has CreateTask() been broken in every single OS release to >date, or am I just very confused, or what? CreateTask() has been broken in every release of amiga.lib (and compiler vendor versions as far as we know). It was fixed a couple of weeks ago.