[comp.sys.amiga] Task Spawning Difficulties

brianr@tekig4.UUCP (06/10/87)

I am slowly working on a real live application for my Amiga, using
Manx' Aztec C compiler (ver 3.40), and I'm having problems creating
an independent task: during the call to the "AddTask" library function,
the Amiga crashes (I can single-step the debugger 20 or 30 instructions
into "AddTask").

I have produced a small test program, included below, which demonstrates
this behavior.  I posted it to Manx' BBS, but so far, nobody there has
suggested a remedy.  Can anyone point out my mistake?


I apologize for posting such a non-contributory article, but I used up
my Manx patience waiting for ver3.4.


---- program follows ---

#include <functions.h>
#include <exec/tasks.h>

struct Task *myslave;
USHORT total;

#define KILLSIG 30L
#define KILLFLAG 0x40000000L

static void Countemup()
{
 int i;
 geta4();
 total = 300;
 if (AllocSignal (KILLSIG) != KILLSIG) goto dumpout;
 total = 0;
 Wait (KILLFLAG);
 for (i = 0; i < 20; i++) total += i;

dumpout:
 RemTask (0L);
}


main()
{
 if ((myslave = CreateTask("Force",22L,Countemup,1400L)) && total < 20)
 {
  printf ("We made a task.  It has set total to %d.\n",total);
  Signal (myslave, KILLFLAG);
  printf ("After running the task, total becomes %d.\n",total);
  }

 else printf ("The task didn't spawn.\n");
 }

------- end of program ---

Thanks in advance,

Brian Rhodefer   ...tektronix!tekig4!brianr

jmsynge@sqm.dec.com.UUCP (06/11/87)

tekig4!brianr writes:

>static void Countemup()
>{
> int i;
> geta4();
> total = 300;
> if (AllocSignal (KILLSIG) != KILLSIG) goto dumpout;
> total = 0;
> Wait (KILLFLAG);
> for (i = 0; i < 20; i++) total += i;
> 
>dumpout:
> RemTask (0L);
>}

	IF I remember correctly, RemTask() REQUIRES a valid pointer to a
Task structure.  Thus the call should be RemTask(FindTask(0L)) and FindTask()
should be declared as struct Task *FindTask().

	Why are you running the task at such a high priority?  The manuals
suggest not running at 20 or higher because certain system tasks (trackdisk)
wouldn't be able to respond quickly enough to interrupts.

Good luck,

James Synge

USENET:  {decvax, ucbvax, allegra}!decwrl!sqm.dec.com!jmsynge
ARPAnet: jmsynge%sqm.DEC@decwrl.DEC.COM

#include <disclaimer.h>
"Ken Olsen can speak for Digital, not me!"

brianr@tekig4.TEK.COM (Brian Rhodefer) (06/19/87)

A few days ago, I posted a plea for help with the problem I had
trying to spawn a new task from a Manx Aztec C program (compiled
with ver 3.40a) on the Amiga: the Amiga would crash during the
AddTask library function call.

Although Ali Ozer (sp?) very kindly sent me a working example
of task spawning,  no one suggested what my difficulty was.
Is it possible then, that the solution merits posting?

With apologies to millions of detective story fans: "DeBUGGER DID IT!"

Since I had never created a new task before, I ran my program
under the Manx debugger, "db", so I could watch what went on
very closely.  I followed my program's execution to a point just
prior to its call on "CreateTask" (A Manx c.lib routine).  I then
set a breakpoint on the instruction following the call, and another
breakpoint on the first instruction of the task I was adding.
(It was merely a subroutine in the code already loaded, so it was
already resident).  The new task was being "Create"d at priority
22, higher than anything else in the system, because I wanted to
ensure that it started immediately.  I expected, when I told the
debugger to "go", that the breakpoint at the beginning of the
new task would be hit; instead, the Amiga crashed (Gurued).

Repeating the proceedure, but single-stepping through "CreateTask"
disclosed that the crash came somewhere in the middle of "CreateTask"s
call on "AddTask".

Was something wrong in the Task structure that "CreateTask" sets up?
I re-ran the program, stopping short of "AddTask", and dumped out the
contents of the structure to a log file.  Since Ali's program ran OK,
I ran the debugger on IT, so I could dump ITS Task structure for
comparison.  It was virtually identical to mine.

Puzzled, I hit "go", AND THE AMIGA CRASHED AGAIN!

I ran my test program by itself, (without the debugger)
and it worked fine.

Further experimentation suggested that the crash occurred BECAUSE
I SET A BREAKPOINT IN A DIFFERENT TASK THAN THE ONE THE DEBUGGER
HAD STARTED UP ON.

Right about then, I figured that a thorough reading of the debugger
manual was in order.  While I could find no explicit caution against
the perils of setting breakpoints in other tasks, I DID find commands
described for opening new debugger windows,

  "..to allow debugging of multiple tasks..".

Using these hitherto ignored commands ("an" and "as"), I was able
to debug my newly created task without crashing. 

I don't know how Manx' debugger works, but It BEHAVES like the
in-circuit emulators I'm familiar with.  To an in-circuit emulator,
a breakpoint is a breakpoint, in fine egalitarian fashion.
In "db", though, breakpoints and tasks are interrelated somehow.
I don't mind having to use multiple windows, even if I don't understand
why it's necessary, except that it seems like the code between the
start of a new task and the first time it does a Wait is
irrevocably inaccessible to the debugger.

Summarizing (with an apology for longwindedness):

  *** ONLY  DEBUG  ONE  TASK  PER  DEBUG  WINDOW! *** 


Brian Rhodefer    ....tektronix!tekig4!brianr

dillon@CORY.BERKELEY.EDU (Matt Dillon) (06/19/87)

	Yup, that would do it.  The reason DB had problems single-stepping
through the AddTask() is obvious... AddTask() probably does a Forbid() for
several very good reasons, but when tracing, any Forbid()'s are effectively
NOP's (since the tracer task must run also).  I've found that putting the
thing in trace mode (bt) usually works better than tracing (t/T).  And,
of course, you can open another window (aN) and do a wait in it (aL) to
catch the created task.

				-Ml:ca