/*
 *
 *   Copyright (c) International Business Machines  Corp., 2002
 *
 *   This program is free software;  you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program;  if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/* Group Bull & IBM Corporation */
/* 11/20/2002	Port to LTP	robbiew@us.ibm.com */
/*                                               jacky.malcles@bull.net */
/* IBM Corporation */
/* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */

/*
 * fptest01.c -- Floating point test.
 *
 * It is taken from a benchmark called "barsim".
 *
 * If the computation arrives at the expected values this routine
 * prints a "passed" message and exits 0.  If an incorrect value is
 * computed a "failed" message is printed and the routine exits 1.
 */

#include <stdio.h>
#include <errno.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define MAGIC1	1632.796126
#define DIFF1	0.001
#define MAGIC2	0.777807
#define DIFF2	0.001
#define EVENTMX	256
#define BIG 1.e50
#define FALSE 0
#define TRUE  1
#define TRYCRIT   1
#define ENTERCRIT 2
#define LEAVECRIT 3
#define ATBARRIER 4
#define ENTERWORK 5
#define LEAVEWORK 6
#define NULLEVENT 999

/** LTP Port **/
#include "test.h"

char *TCID = "fptest01";	/* Test program identifier.    */
int TST_TOTAL = 1;		/* Total number of test cases. */
/**************/

int init();
int doevent();
int term();
int addevent();
double gauss();
void gaussinit();
struct event {
	int proc;
	int type;
	double time;
};

struct event eventtab[EVENTMX];
struct event rtrevent;
int waiting[EVENTMX];		/* array of waiting processors */
int nwaiting;			/* number of waiting processors */
double global_time;		/* global clock */
double lsttime;			/* time used for editing */
double dtc, dts, alpha;		/* timing parameters */
int nproc;			/* number of processors */
int barcnt;			/* number of processors ATBARRIER */
int ncycle;			/* number of cycles completed */
int ncycmax;			/* number of cycles to run */
int critfree;			/* TRUE if critical section not occupied */
int gcount;			/* # calls to gauss */

struct event *nextevent();

int main(int argc, char **argv)
{
	struct event *ev;

	nproc = 128;
	ncycmax = 10;
	dtc = 0.01;
	dts = 0.0;
	alpha = 0.1;

	init();

	while ((ev = nextevent()) != NULL) {
		doevent(ev);
	}

	term();
	tst_resm(TPASS, "PASS");
	tst_exit();
}

/*
	initialize all processes to "entering work section"
*/
int init()
{
	int p;
	double dtw, dtwsig;

	ncycle = 0;
	global_time = 0;
	lsttime = 0;
	barcnt = 0;
	nwaiting = 0;
	critfree = TRUE;

	dtw = 1. / nproc;	/* mean process work time */
	dtwsig = dtw * alpha;	/* std deviation of work time */
	gaussinit(dtw, dtwsig);

	for (p = 1; p <= nproc; p++) {
		eventtab[p].type = NULLEVENT;
	}

	for (p = 1; p <= nproc; p++) {
		addevent(ENTERWORK, p, global_time);
	}

	return (0);
}

/*
	print edit quantities
*/
int term()
{
	double avgspd;
	double t_total = 0.0;
	double v;
	int i;

	for (i = 0; i < nproc; i++)
		t_total += eventtab[i].time;

	avgspd = ncycle / global_time;

	v = t_total - MAGIC1;
	if (v < 0.0)
		v *= -1.0;

	if (v > DIFF1) {
		tst_resm(TFAIL, "FAIL");
		v = t_total - MAGIC1;
		tst_resm(TINFO, "t_total = %.15f\n", t_total);
		tst_resm(TINFO, "expected  %.15f\n", MAGIC1);
		tst_resm(TINFO, "diff = %.15f\n", v);
		tst_exit();
	}

	v = avgspd - MAGIC2;
	if (v < 0.0)
		v *= -1.0;

	if (v > DIFF2) {
		tst_resm(TFAIL, "FAIL");
		v = avgspd - MAGIC2;
		tst_resm(TINFO, "avgspd  = %.15f\n", avgspd);
		tst_resm(TINFO, "expected  %.15f\n", MAGIC2);
		tst_resm(TINFO, "diff = %.15f\n", v);
		tst_exit();
	}
	return (0);
}

/*
	add an event to the event queue
*/
int addevent(int type, int proc, double t)
{
	int i;
	int ok = FALSE;

	for (i = 1; i <= nproc; i++) {
		if (eventtab[i].type == NULLEVENT) {
			eventtab[i].type = type;
			eventtab[i].proc = proc;
			eventtab[i].time = t;
			ok = TRUE;
			break;
		}
	}
	if (ok)
		return (0);
	else
		tst_brkm(TBROK, NULL, "No room for event");
	return (0);
}

/*
	get earliest event in event queue
*/
struct event *nextevent()
{
	double mintime = BIG;
	int imin = 0;
	int i;

	for (i = 1; i <= nproc; i++) {
		if (eventtab[i].type != NULLEVENT && eventtab[i].time < mintime) {
			imin = i;
			mintime = eventtab[i].time;
		}
	}

	if (imin) {
		rtrevent.type = eventtab[imin].type;
		rtrevent.proc = eventtab[imin].proc;
		rtrevent.time = eventtab[imin].time;
		eventtab[imin].type = NULLEVENT;
		return (&rtrevent);
	} else
		return (NULL);
}

/*
	add a processor to the waiting queue
*/
int addwaiting(p)
int p;
{
	waiting[++nwaiting] = p;
	return (0);
}

/*
	remove the next processor from the waiting queue
*/
int getwaiting()
{
	if (nwaiting)
		return (waiting[nwaiting--]);
	else
		return (0);
}

double dtcrit()
{
	return (dtc);
}

double dtspinoff()
{
	return (dts);
}

double dtwork()
{
	return (gauss());
}

/*
	take the action prescribed by 'ev', update the clock, and
	generate any subsequent events
*/
int doevent(ev)
struct event *ev;
{
	double nxttime;
	int i, p, proc;

	global_time = ev->time;
	proc = ev->proc;

	switch (ev->type) {
	case TRYCRIT:
		if (critfree == TRUE)
			addevent(ENTERCRIT, proc, global_time);
		else
			addwaiting(proc);
		break;
	case ENTERCRIT:
		critfree = FALSE;
		nxttime = global_time + dtcrit();
		addevent(LEAVECRIT, proc, nxttime);
		break;
	case LEAVECRIT:
		critfree = TRUE;
		addevent(ATBARRIER, proc, global_time);
		if ((p = getwaiting()) != 0) {
			nxttime = global_time;
			addevent(ENTERCRIT, p, nxttime);
		}
		break;
	case ATBARRIER:
		barcnt++;
		if (barcnt == nproc) {
			nxttime = global_time;
			for (i = 1; i <= nproc; i++) {
				nxttime += dtspinoff();
				addevent(ENTERWORK, i, nxttime);
			}
			barcnt = 0;
			ncycle++;
		}
		break;
	case ENTERWORK:
		nxttime = global_time + dtwork();
		if (ncycle < ncycmax)
			addevent(LEAVEWORK, proc, nxttime);
		break;
	case LEAVEWORK:
		addevent(TRYCRIT, proc, global_time);
		break;
	default:
		tst_brkm(TBROK, NULL, "Illegal event");
		break;
	}
	return (0);
}

static int alternator = 1;
static double mean;
static double stdev;
static double u1, u2;
static double twopi;

void gaussinit(double m, double s)
{
	mean = m;
	stdev = s;
	twopi = 2. * acos((double)-1.0);
	u1 = twopi / 400.0;
	u2 = twopi / 500.0;
}

double gauss()
{
	double x1, x2;

	gcount++;

	u1 += u2;
	if (u1 > 0.99)
		u1 = twopi / 500.0;
	u2 += u1;
	if (u2 > 0.99)
		u2 = twopi / 400.0;

	if (alternator == 1) {
		alternator = -1;
		x1 = sqrt(-2.0 * log(u1)) * cos(twopi * u2);
		return (mean + stdev * x1);
	} else {
		alternator = 1;
		x2 = sqrt(-2.0 * log(u1)) * sin(twopi * u2);
		return (mean + stdev * x2);
	}
}
