[comp.sys.amiga.programmer] CreateTask

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.