[comp.sys.amiga.tech] Example program which starts up a whole bunch of sub tasks

dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (05/22/89)

	Aztec C, 16 or 32 bit ints, small or large data model.

	1> tasks [#-of-tasks]

	N tasks (default 1) are started up simultaniously and each uses the
	timer.device to wait for differing amounts of time before asking the
	main program to kill them.

					-Matt

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <exec/lists.h>
#include <devices/timer.h>
#include <stdio.h>

#define STACK_SIZE 1000L

#define lsizeof(type)   ((long)sizeof(type))

typedef struct MsgPort	PORT;
typedef struct Message	EXECMSG;
typedef struct Task	TASK;
typedef struct timerequest  IOT;

extern TASK	*FindTask();
extern TASK	*CreateTask();
extern void	*GetMsg();
extern void	*AllocMem();
extern PORT	*CreatePort();
TASK *runtask();
void killtask();
void mytask();

extern int Enable_Abort;

PORT	*KillPort;
short	SyncSig;
short	NumRunning;
short	WowItWorked;
long	Secs = 1;	/*  base # of seconds task should wait	*/
IOT	Iot;		/*  master skeleton timer request	*/

main(ac, av)
char *av[];
{
    EXECMSG *msg;
    short i;

    Enable_Abort = 0;			/*  don't allow user abort          */
    SyncSig  = AllocSignal(-1L);        /*  used for child-parent syncup    */
    if (SyncSig < 0)
	goto fail;
    KillPort = CreatePort(NULL,0L);     /*  child informs parent its done   */
    if (KillPort == NULL)
	goto fail;
					/*  used for child's delay          */
    if (OpenDevice("timer.device", (long)UNIT_VBLANK, &Iot, 0L)) {
	puts("unable to open timer device!");
	goto fail;
    }
    Iot.tr_node.io_Command = TR_ADDREQUEST;

    i = (ac == 2) ? atoi(av[1]) : 1;    /*  # of tasks to startup           */
    printf("Starting up %d tasks\n", i);

    while (i--) {                       /*  start tasks                     */
	if (CreateTask("my-task", (long)FindTask(0L)->tc_Node.ln_Pri, mytask, STACK_SIZE)) {
	    ++NumRunning;
	    Wait(1L << SyncSig);
	}
	++Secs;
    }

    while (NumRunning) {
	printf("%d Wait", WowItWorked);
	fflush(stdout);
	WaitPort(KillPort);
	msg = GetMsg(KillPort);
	printf(", remove %08lx\n", msg->mn_Node.ln_Name);

	RemTask(msg->mn_Node.ln_Name);
	--NumRunning;
    }
    printf("All done, final value %d\n", WowItWorked);
fail:
    if (SyncSig >= 0)
	FreeSignal((long)SyncSig);
    if (KillPort)
	DeletePort(KillPort);
    if (Iot.tr_node.io_Device)
	CloseDevice(&Iot);
}

void
mytask()
{
    PORT    port;		/*  reply port for IO	    */
    IOT     iot;		/*  timer request	    */
    long    time;		/*  time delay		    */

    /*
     *	TASK SETUP
     *	    small data model get base ptr
     *	    signal parent that we retrieved the Secs field
     */

    geta4();
    time = Secs;
    Signal(KillPort->mp_SigTask, 1L << SyncSig);

    /*
     *	INITIALIZATION
     *	    setup reply port for io request
     *	    setup io request from template
     */

    port.mp_Flags   = PA_SIGNAL;
    port.mp_SigBit  = AllocSignal(-1L);
    port.mp_SigTask = FindTask(0L);
    NewList(&port.mp_MsgList);
    iot = Iot;
    iot.tr_node.io_Message.mn_ReplyPort = &port;
    iot.tr_time.tv_secs = time;

    /*
     *	RUN
     */

    ++WowItWorked;		/*  Just so you know it ran		*/

    DoIO(&iot);                 /*  Wait for specified time interval    */

    /*
     *	DONE
     *	    setup exec message and send to parent
     *	    wait forever (for parent to kill me)
     *	    don't worry about freeing the signal we allocated...
     */

    {
	EXECMSG msg;		    /*	reply msg to main	*/
	msg.mn_Node.ln_Name = (char *)FindTask(0L);
	PutMsg(KillPort, &msg);
	Wait(0L);
    }
}