/*
 *	ListTasks.c
 *
 *	This program produces a list of executing tasks on its standard
 *	output.
 *
 *	Program		Date		Action
 *	D. Thomas	19 April 1987	v1.0 Initial Coding.
 *
 */

#include "exec/execbase.h"
#include "functions.h"

extern struct ExecBase *SysBase;	/* Exec's base ptr */

static char *state[] = {
  "Invalid",
  "Added",
  "Running",
  "Ready",
  "Waiting",
  "Except",
  "Removed"
};

main ()

{

  register struct Task *t;	/* ptr to scan task list */
  register struct List  head;	/* for my copy of the task list */

  NewList (&head);

  Disable ();

  if (onetask (SysBase->ThisTask, &head))
    cleanup (&head);

  if (gettask (&SysBase->TaskReady, &head))
    cleanup (&head);

  if (gettask (&SysBase->TaskWait, &head))
    cleanup (&head);

  Enable ();

  puts (" Pri State   SigAlloc  SigWait SigRecvd SigExcpt Stak StkU Name");

  while (t = (struct Task *) RemHead (&head)) {

    printf ("%4d %-7.7s %8lx %8lx %8lx %8lx %4.4lx %4.4lx %s\n",
      t->tc_Node.ln_Pri, state[t->tc_State], t->tc_SigAlloc,
      t->tc_SigWait, t->tc_SigRecvd, t->tc_SigExcept,
      (ULONG) t->tc_SPUpper - (ULONG) t->tc_SPLower,
      (ULONG) t->tc_SPUpper - (ULONG) t->tc_SPReg,
      t->tc_Node.ln_Name);
    FreeMem (t->tc_Node.ln_Name, (long) strlen (t->tc_Node.ln_Name) + 1);
    FreeMem (t, (long) sizeof *t);

  }

  exit (0L);

}

freelist (l)

struct List *l;

{

  struct Task *t;

  while (t = (struct Task *) RemHead (l)) {
    FreeMem (t->tc_Node.ln_Name, (long) strlen (t->tc_Node.ln_Name) + 1);
    FreeMem (t, (long) sizeof *t);
  }

}

cleanup (l)

struct List *l;

{

  Enable ();
  freelist (l);
  puts ("Out of Memory!");
  exit (0);

}

gettask (tl, l)

struct List *tl;
struct List *l;

{

  register struct Task *t;

  for (t = (struct Task *) tl->lh_Head;
       t->tc_Node.ln_Succ;
       t = (struct Task *) t->tc_Node.ln_Succ)
    if (onetask (t, l))
      return TRUE;

  return FALSE;

}

onetask (t, l)

struct Task *t;
struct List *l;

{

  register struct Task *tc;

  if (!(tc = (struct Task *) AllocMem ((long) sizeof *t, 0L)))
      return TRUE;
  *tc = *t;
  if (!(tc->tc_Node.ln_Name = (char *) AllocMem ((long) strlen (t->tc_Node.ln_Name) + 1, 0L))) {
    FreeMem (tc, (long) sizeof *tc);
    return TRUE;
  }
  strcpy (tc->tc_Node.ln_Name, t->tc_Node.ln_Name);
  AddTail (l, tc);

  return FALSE;

}
