/* This shows how to create a Fork function with a priority level for the		*/
/* Transputer. The main problem on the Transputer is the schedular is implemented	*/
/* in silicon and has only two levels - high and low priority				*/
/* ARM and C40 users do not have to be so devious. They can have multiple priority 	*/
/* schedulars implemented in software.							*/

/* Caution: If you loop continuously in high priority on a transputer there is nothing 	*/
/* the system can do to get processor time, so be warned !!! 				*/

/* To compile just type:								*/
/* c -o hifork hifork.c									*/

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <helios.h>
#include <nonansi.h>
#include <process.h>
#include <asm.h>

void PriFork (int Priority, word stsize, VoidFnPtr func, word argsize, word parameter, ...)
{
   int notused;
   char *args;
   char *process;

   notused = parameter;
   args = ((char *) &argsize) + sizeof (argsize);
   process = (char *) NewProcess (stsize, func, argsize);

   if (process == (char *) 0) {
      printf ("PriFork: <NewProcess> error\n");
      exit(1);
   }

   memcpy (process, args, argsize);
   /* Normally you would use ExecProcess but the system blocks hi priority */ 
   StartProcess ((void *)((word) process), Priority);
   return;

}

void hello(void)
{
   word pri;

   /* for those who do not believe system calls, we shall make an assembler call, to check priority !! */
   pri = ldpri_();

   /* use IOdebug to report the priority as C streams will get confused with multiple IO threads */
   if (pri)
     IOdebug("Running at low priority %d\n",pri);
   else
     IOdebug("Running at high priority %d\n",pri);

}

int main(void)
{
   printf("starting high priority thread\n");
   PriFork( 0,1500,hello,0,0);
   printf("starting low priority thread\n");
   PriFork( 1,1500,hello,0,0);
   sleep(1);
}
