/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by Mike Parker.			    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/file.h>
#include <signal.h>
#include <vax/mtpr.h>

char *malloc();

#include "../sys/rciext/kaioctl.h"
#include "../sys/rciext/kamsgs.h"
#include "../sys/rciext/kacomm.h"

#include "getmapplace.h"
#include "uapage.h"

char *sbrk();

char device[] = "/dev/ka1";
int cpuno = 1;
int kafd;
struct blkdesc desc;
char msg[1024];
extern char etext;
extern char edata;
extern char end;
char Share[2048];
char *share;
int *value;

int Xint;

int slavemain();
int slaveast();

getpfn()
{
 register int p0br; /* r11 */

 p0br = P0BR;
 asm("mfpr r11,r11");
 Xint = ((int *)p0br)[Xint>>9];
}

int cpuNo;

slavecrashed()
{
	CRASHINFO ci;
	char errmsg[256];

	ioctl(kafd,KAIOC_GETCRASH,&ci);
	crashMessage(errmsg,&ci,0);
	printf("slave crash: %s\n",errmsg);
	exit(0);
}

main(argc, argv)
int argc;
char **argv;
{
 if (argc != 2)
  { fprintf(stderr,"Usage: %s cpu-number\n",argv[0]);
    exit(1);
  }

	cpuNo = atoi (*++argv);

	if (cpuNo < 0 || cpuNo > 3)
	 { fprintf(stderr,"%s: bad cpu number `%s'\n",argv[1]);
	   exit(1);
	 }
	printf ("cpuNo = %d\n", cpuNo);
	kafd = open(device,O_RDWR,0);
	if (kafd < 0)
	 { perror(device);
	   exit(1);
	 }
	share = (char *) ((((int)&Share[0])+1023)&~1023);
	value = (int *) share;
	mth$int_random();
	sendclear(kafd);
	sendtext(kafd);
	senddata(kafd);
	sendexec(kafd,slavemain);
	signal(SIGXCPU,slavecrashed);
	 { int sig;
	   sig = SIGXCPU;
	   ioctl(kafd,KAIOC_ONCRASH,&sig);
	 }
	while (1)
	 { sigpause(0);
	 }
}

static int foo = 0;
static int bar = -1;

#include "getmapplace.h"

int *astblock;

struct kabboard *bboard0;
struct kabboard *bboard1;
UAPAGE *uapage;

#define TIME()	bboard1->time_rt[cpuNo]

timeit(fxn,name)
register int (*fxn)();
char *name;
{
 register int t1;
 register int t2;
 register int n;
 int m;
 int looptime;
 int totaltime;

 n = 0;
 t1 = TIME();
 while (t1 == TIME()) ;
 t1 = TIME() + 1;
 while (t1 != TIME()) ;
 do
  { (*fxn)();
    n ++;
  } while (t1 == TIME());
 n *= 3000;
 m = n;
 t1 = TIME() + 1;
 while (t1 != TIME()) ;
 for (;n>0;n--)
  { (*fxn)();
  }
 t2 = TIME() - t1;
 totaltime = t2;
 n = m;
 t1 = TIME() + 1;
 while (t1 != TIME()) ;
 for (;n>0;n--)
  { ;
  }
 t2 = TIME() - t1;
 looptime = t2;
 t2 = totaltime - looptime;
 printf("%s: %d loops, %d.%02d seconds: %g us/loop  (loop %g%%)\n",
			name,
			m,
			t2/100, t2%100,
			(t2*10000)/(double)m,
			(100*looptime)/(double)totaltime );
}

timer(time)
{
 int realtime;
 char c;

 realtime = TIME();
 printf("&c = %#08x  time = %d\n",(int)&c,realtime);
 schedast(cpuNo,realtime+29,timer,0);
}

delay(nticks)
int nticks;
{
 int t;

 t = TIME() + nticks;
 while (t > TIME()) ;
}

nullfxn()
{
}

#define BLOCK_ASTS()	\
	uapage->block_asts = 1;
#define UNBLOCK_ASTS()	\
	uapage->block_asts = 0; if (uapage->astqsize > 0) clearast();

slavemain()
{
	char cmd[2];
	int time, time1, time2, time3;
	int i;
	int qsize;

	uapage = (UAPAGE*)(getmapplace (MAP_UAPAGE));
	astblock = &(uapage->block_asts);
	printf ("astblock = 0x%x\n", astblock);

	bboard0 = (struct kabboard*) getmapplace (MAP_BBOARD(0));
	bboard1 = (struct kabboard*) getmapplace (MAP_BBOARD(1));

	time = bboard1->time_rt[cpuNo];

	printf ("setting up ast on cpu %d:\n", cpuNo);
	schedast (cpuNo, TIME()+100, timer, 0);

	for (i=0; i<3000000; i++)
	   ;
/*	blockast();*/
	BLOCK_ASTS();

	printf ("ASTs should be blocked\n");

	for (i=0; i<3000000; i++)
	   ;

	printf ("Unblocking ASTs, qsize = %d\n", uapage->astqsize);

	UNBLOCK_ASTS();
/*	clearast();	*/
	qsize = uapage->astqsize;

	printf ("qsize = %d\n", qsize);

	for (i=0; i<500000; i++)
	   ;
	blockast();

	while (1)
	   ;
}

dummy()
{
}
