[comp.sys.amiga.tech] need help with tasks

denis@vlsisj.VLSI.COM (/) (05/19/89)

Help! When I run the code below I meet the Guru! Can anyone help me out?

I am trying to write a program that starts up and creates several tasks.
The C program has all of the code for each of the tasks. After the
main prcedure starts the tasks I want it to wait for all of the tasks to
finish. After all tasks have finished the main program should remove them
and exit. My first attempt is shown below. I wrote a simple semaphore
server process so that the task can signal the main program when it is
done. Everything seems to work fine until I run AddTask. At that point
my system gurus. What am I doing wrong? Do I need to use something other
than the address of the procedure in AddTask? I am using the MANX C compiler
with sdb. Any ideas would be appreciated!

I also have a question on how a task can wait to be deleted. I would like
to just put it to sleep. The only way I could think of to do this is to
wait on a signal that will never happen. Is there a better way?

#include <exec/memory.h>
#include <exec/tasks.h>
#include <functions.h>
#include <stdio.h>
#include "semaphore.h"

#define STACK_SIZE ((long) 1000)

long uid = 0;

void task()
{
  long signal;

  signal = AllocSignal((long) -1);

  semaphore_V(uid);

  if (signal != -1) {
    Wait(signal);
  } else {
    /* this is bad, how else can we wait to be removed? */
    while (TRUE);
  }
}

struct Task *start_task()
{
  struct Task *p_task;
  APTR p_stack;

  p_stack = AllocMem(STACK_SIZE, MEMF_CLEAR);
  if (! p_stack) {
    /* error: not enough memory */
    return NULL;
  }

  p_task = AllocMem((long) sizeof(struct Task), MEMF_CLEAR |
    MEMF_PUBLIC);
  if (! p_task) {
    /* error: not enought memory */
    FreeMem(p_stack, STACK_SIZE);
    return NULL;
  }

  p_task->tc_Node.ln_Type = NT_TASK;
  p_task->tc_Node.ln_Name = "task";
  p_task->tc_SPLower = p_stack;
  p_task->tc_SPUpper = p_stack + STACK_SIZE;
  p_task->tc_SPReg = p_task->tc_SPUpper;

  AddTask(p_task, task, NULL);

  return p_task;
}

void stop_task(p_task)
struct Task *p_task;
{
  RemTask(p_task);
/*
  FreeMem(p_task->tc_SPLower, STACK_SIZE);
  FreeMem(p_task, (long) sizeof(struct Task));
*/
}

main()
{
  struct Task *p_task;
  long uid;

  if (! semaphore_init()) {
    fprintf(stderr, "can't init semaphores...\n");
    exit(1);
  }

  uid = semaphore_new(0L);
  if (! uid) {
    fprintf(stderr, "can't create a new semaphore...\n");
    exit(1);
  }

  p_task = start_task();

  semaphore_P(uid);

  stop_task(p_task);

  semaphore_delete(uid);

  semaphore_term();
}
-- 
Denis Bohm    (usenet: decwrl!vlsisj!denis)

deven@rpi.edu (Deven Corzine) (05/21/89)

In article <15230@vlsisj.VLSI.COM> denis@vlsisj.VLSI.COM (/) writes:

>    /* this is bad, how else can we wait to be removed? */
>    while (TRUE);

    Wait(0L);

Deven
--
shadow@[128.113.10.2]   <shadow@pawl.rpi.edu> Deven T. Corzine (518) 272-5847
shadow@[128.113.10.201] <shadow@acm.rpi.edu>  2346 15th St.    Pi-Rho America
deven@rpitsmts.bitnet   <userfxb6@rpitsmts>   Troy, NY 12180-2306  <<tionen>>
"Simple things should be simple and complex things should be possible." - A.K.