1bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/*
2bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *
3bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   Copyright (c) International Business Machines  Corp., 2002
4bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *
5bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   This program is free software;  you can redistribute it and/or modify
6bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   it under the terms of the GNU General Public License as published by
7bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   the Free Software Foundation; either version 2 of the License, or
8bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   (at your option) any later version.
9bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *
10bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   This program is distributed in the hope that it will be useful,
11bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   the GNU General Public License for more details.
14bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *
15bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   You should have received a copy of the GNU General Public License
16bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *   along with this program;  if not, write to the Free Software
174548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew */
19bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
20bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/* Group Bull & IBM Corporation */
214b264476cb3f10b994b39e4b61cca0594ea79279robbiew/* 11/20/2002	Port to LTP	robbiew@us.ibm.com */
222c28215423293e443469a07ae7011135d058b671Garrett Cooper/*                                               jacky.malcles@bull.net */
23bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/* IBM Corporation */
244b264476cb3f10b994b39e4b61cca0594ea79279robbiew/* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
25bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
26bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/*
27bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew * fptest01.c -- Floating point test.
28bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *
29bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew * It is taken from a benchmark called "barsim".
30bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew *
31bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew * If the computation arrives at the expected values this routine
32bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew * prints a "passed" message and exits 0.  If an incorrect value is
33bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew * computed a "failed" message is printed and the routine exits 1.
34bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew */
35bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
36bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include <stdio.h>
37a70576c4834d89f937e46698fef4114736cce4d7robbiew#include <errno.h>
38bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include <math.h>
39bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include <stdlib.h>
40bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include <unistd.h>
41bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include <sys/types.h>
42bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include <sys/stat.h>
43bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include <fcntl.h>
44bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
454b264476cb3f10b994b39e4b61cca0594ea79279robbiew#define MAGIC1	1632.796126
464b264476cb3f10b994b39e4b61cca0594ea79279robbiew#define DIFF1	0.001
474b264476cb3f10b994b39e4b61cca0594ea79279robbiew#define MAGIC2	0.777807
484b264476cb3f10b994b39e4b61cca0594ea79279robbiew#define DIFF2	0.001
494b264476cb3f10b994b39e4b61cca0594ea79279robbiew#define EVENTMX	256
50bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define BIG 1.e50
51bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define FALSE 0
52bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define TRUE  1
53bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define TRYCRIT   1
54bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define ENTERCRIT 2
55bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define LEAVECRIT 3
56bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define ATBARRIER 4
57bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define ENTERWORK 5
58bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define LEAVEWORK 6
59bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#define NULLEVENT 999
60bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
61bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/** LTP Port **/
62bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include "test.h"
63bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
64354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaochar *TCID = "fptest01";	/* Test program identifier.    */
65354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint TST_TOTAL = 1;		/* Total number of test cases. */
66bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/**************/
67bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
68bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiewstruct event {
694b264476cb3f10b994b39e4b61cca0594ea79279robbiew	int proc;
704b264476cb3f10b994b39e4b61cca0594ea79279robbiew	int type;
714b264476cb3f10b994b39e4b61cca0594ea79279robbiew	double time;
72354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao};
73bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
74829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int init(void);
75829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int doevent(struct event *);
76829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int term(void);
77829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int addevent(int, int, double);
78829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger
79829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic void gaussinit(double, double);
80829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic double gauss(void);
81829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger
82bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiewstruct event eventtab[EVENTMX];
83bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiewstruct event rtrevent;
84354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint waiting[EVENTMX];		/* array of waiting processors */
85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint nwaiting;			/* number of waiting processors */
869e78ade7d6c596a709d0228909bd5d37a85cf4a5vapierdouble global_time;		/* global clock */
87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaodouble lsttime;			/* time used for editing */
88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaodouble dtc, dts, alpha;		/* timing parameters */
89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint nproc;			/* number of processors */
90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint barcnt;			/* number of processors ATBARRIER */
91354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint ncycle;			/* number of cycles completed */
92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint ncycmax;			/* number of cycles to run */
93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint critfree;			/* TRUE if critical section not occupied */
94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint gcount;			/* # calls to gauss */
95bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
96829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic struct event *nextevent(void);
97bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint main(int argc, char **argv)
99bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
1004b264476cb3f10b994b39e4b61cca0594ea79279robbiew	struct event *ev;
101bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
1024b264476cb3f10b994b39e4b61cca0594ea79279robbiew	nproc = 128;
1034b264476cb3f10b994b39e4b61cca0594ea79279robbiew	ncycmax = 10;
1044b264476cb3f10b994b39e4b61cca0594ea79279robbiew	dtc = 0.01;
1054b264476cb3f10b994b39e4b61cca0594ea79279robbiew	dts = 0.0;
1064b264476cb3f10b994b39e4b61cca0594ea79279robbiew	alpha = 0.1;
107bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
1084b264476cb3f10b994b39e4b61cca0594ea79279robbiew	init();
109bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while ((ev = nextevent()) != NULL) {
1114b264476cb3f10b994b39e4b61cca0594ea79279robbiew		doevent(ev);
1124b264476cb3f10b994b39e4b61cca0594ea79279robbiew	}
113bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
1144b264476cb3f10b994b39e4b61cca0594ea79279robbiew	term();
115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	tst_resm(TPASS, "PASS");
1164b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	tst_exit();
117bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
118bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
119bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/*
1204b264476cb3f10b994b39e4b61cca0594ea79279robbiew	initialize all processes to "entering work section"
121bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew*/
122829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int init(void)
123bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
1244b264476cb3f10b994b39e4b61cca0594ea79279robbiew	int p;
1254b264476cb3f10b994b39e4b61cca0594ea79279robbiew	double dtw, dtwsig;
126bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
127354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	ncycle = 0;
128354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	global_time = 0;
129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	lsttime = 0;
130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	barcnt = 0;
131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	nwaiting = 0;
132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	critfree = TRUE;
133bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
134354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	dtw = 1. / nproc;	/* mean process work time */
135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	dtwsig = dtw * alpha;	/* std deviation of work time */
136354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	gaussinit(dtw, dtwsig);
137bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
138354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (p = 1; p <= nproc; p++) {
1394b264476cb3f10b994b39e4b61cca0594ea79279robbiew		eventtab[p].type = NULLEVENT;
1404b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	}
141bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (p = 1; p <= nproc; p++) {
143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		addevent(ENTERWORK, p, global_time);
1444b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	}
145bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return (0);
147bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
149bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/*
1504b264476cb3f10b994b39e4b61cca0594ea79279robbiew	print edit quantities
151bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew*/
152829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int term(void)
153bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
1544b264476cb3f10b994b39e4b61cca0594ea79279robbiew	double avgspd;
1554b264476cb3f10b994b39e4b61cca0594ea79279robbiew	double t_total = 0.0;
1564b264476cb3f10b994b39e4b61cca0594ea79279robbiew	double v;
1574b264476cb3f10b994b39e4b61cca0594ea79279robbiew	int i;
1584b264476cb3f10b994b39e4b61cca0594ea79279robbiew
159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 0; i < nproc; i++)
1604b264476cb3f10b994b39e4b61cca0594ea79279robbiew		t_total += eventtab[i].time;
1614b264476cb3f10b994b39e4b61cca0594ea79279robbiew
162354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	avgspd = ncycle / global_time;
1634b264476cb3f10b994b39e4b61cca0594ea79279robbiew
1644b264476cb3f10b994b39e4b61cca0594ea79279robbiew	v = t_total - MAGIC1;
1654b264476cb3f10b994b39e4b61cca0594ea79279robbiew	if (v < 0.0)
1664b264476cb3f10b994b39e4b61cca0594ea79279robbiew		v *= -1.0;
1674b264476cb3f10b994b39e4b61cca0594ea79279robbiew
1684b264476cb3f10b994b39e4b61cca0594ea79279robbiew	if (v > DIFF1) {
169354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TFAIL, "FAIL");
1704b264476cb3f10b994b39e4b61cca0594ea79279robbiew		v = t_total - MAGIC1;
171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TINFO, "t_total = %.15f\n", t_total);
172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TINFO, "expected  %.15f\n", MAGIC1);
173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TINFO, "diff = %.15f\n", v);
1744b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		tst_exit();
1754b264476cb3f10b994b39e4b61cca0594ea79279robbiew	}
1764b264476cb3f10b994b39e4b61cca0594ea79279robbiew
1774b264476cb3f10b994b39e4b61cca0594ea79279robbiew	v = avgspd - MAGIC2;
1784b264476cb3f10b994b39e4b61cca0594ea79279robbiew	if (v < 0.0)
1794b264476cb3f10b994b39e4b61cca0594ea79279robbiew		v *= -1.0;
1804b264476cb3f10b994b39e4b61cca0594ea79279robbiew
1814b264476cb3f10b994b39e4b61cca0594ea79279robbiew	if (v > DIFF2) {
182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TFAIL, "FAIL");
1834b264476cb3f10b994b39e4b61cca0594ea79279robbiew		v = avgspd - MAGIC2;
184354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TINFO, "avgspd  = %.15f\n", avgspd);
185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TINFO, "expected  %.15f\n", MAGIC2);
186354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TINFO, "diff = %.15f\n", v);
1874b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		tst_exit();
1884b264476cb3f10b994b39e4b61cca0594ea79279robbiew	}
189354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return (0);
190bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
192bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/*
1934b264476cb3f10b994b39e4b61cca0594ea79279robbiew	add an event to the event queue
194bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew*/
195829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int addevent(int type, int proc, double t)
196bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
1974b264476cb3f10b994b39e4b61cca0594ea79279robbiew	int i;
198354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int ok = FALSE;
199354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
200354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 1; i <= nproc; i++) {
201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (eventtab[i].type == NULLEVENT) {
202354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			eventtab[i].type = type;
203354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			eventtab[i].proc = proc;
204354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			eventtab[i].time = t;
205354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			ok = TRUE;
2064b264476cb3f10b994b39e4b61cca0594ea79279robbiew			break;
2074b264476cb3f10b994b39e4b61cca0594ea79279robbiew		}
2084b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	}
2092c28215423293e443469a07ae7011135d058b671Garrett Cooper	if (ok)
210354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return (0);
2114b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	else
2124b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		tst_brkm(TBROK, NULL, "No room for event");
213354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return (0);
214bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
215354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
216bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/*
2174b264476cb3f10b994b39e4b61cca0594ea79279robbiew	get earliest event in event queue
218bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew*/
219829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic struct event *nextevent(void)
220bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
221354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	double mintime = BIG;
222354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int imin = 0;
2234b264476cb3f10b994b39e4b61cca0594ea79279robbiew	int i;
224bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
225354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 1; i <= nproc; i++) {
226354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (eventtab[i].type != NULLEVENT && eventtab[i].time < mintime) {
227354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			imin = i;
228354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			mintime = eventtab[i].time;
2294b264476cb3f10b994b39e4b61cca0594ea79279robbiew		}
2304b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	}
2312c28215423293e443469a07ae7011135d058b671Garrett Cooper
2324b264476cb3f10b994b39e4b61cca0594ea79279robbiew	if (imin) {
2334b264476cb3f10b994b39e4b61cca0594ea79279robbiew		rtrevent.type = eventtab[imin].type;
2344b264476cb3f10b994b39e4b61cca0594ea79279robbiew		rtrevent.proc = eventtab[imin].proc;
2354b264476cb3f10b994b39e4b61cca0594ea79279robbiew		rtrevent.time = eventtab[imin].time;
236354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		eventtab[imin].type = NULLEVENT;
237354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return (&rtrevent);
2384b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	} else
239cf0d626fe6224db3c714843dc7007e9f81d94a80Cyril Hrubis		return (NULL);
240bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
241354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
242bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/*
2434b264476cb3f10b994b39e4b61cca0594ea79279robbiew	add a processor to the waiting queue
244bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew*/
245829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int addwaiting(int p)
246bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
247354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	waiting[++nwaiting] = p;
248354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return (0);
249bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
250354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
251bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/*
2524b264476cb3f10b994b39e4b61cca0594ea79279robbiew	remove the next processor from the waiting queue
253bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew*/
254829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int getwaiting(void)
255bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
2564b264476cb3f10b994b39e4b61cca0594ea79279robbiew	if (nwaiting)
257354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return (waiting[nwaiting--]);
2584b264476cb3f10b994b39e4b61cca0594ea79279robbiew	else
259354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return (0);
260bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
261354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
262829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic double dtcrit(void)
263bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
264354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return (dtc);
265bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
266354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
267829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic double dtspinoff(void)
268bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
269354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return (dts);
270bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
271354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
272829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic double dtwork(void)
273bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
274354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return (gauss());
275bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
276354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
277bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew/*
2784b264476cb3f10b994b39e4b61cca0594ea79279robbiew	take the action prescribed by 'ev', update the clock, and
2794b264476cb3f10b994b39e4b61cca0594ea79279robbiew	generate any subsequent events
280bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew*/
281829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic int doevent(struct event *ev)
282bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
2834b264476cb3f10b994b39e4b61cca0594ea79279robbiew	double nxttime;
2844b264476cb3f10b994b39e4b61cca0594ea79279robbiew	int i, p, proc;
2854b264476cb3f10b994b39e4b61cca0594ea79279robbiew
2869e78ade7d6c596a709d0228909bd5d37a85cf4a5vapier	global_time = ev->time;
2874b264476cb3f10b994b39e4b61cca0594ea79279robbiew	proc = ev->proc;
2884b264476cb3f10b994b39e4b61cca0594ea79279robbiew
2894b264476cb3f10b994b39e4b61cca0594ea79279robbiew	switch (ev->type) {
2904b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	case TRYCRIT:
291354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (critfree == TRUE)
292354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			addevent(ENTERCRIT, proc, global_time);
2934b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		else
2944b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper			addwaiting(proc);
2954b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		break;
2964b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	case ENTERCRIT:
2974b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		critfree = FALSE;
298354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		nxttime = global_time + dtcrit();
299354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		addevent(LEAVECRIT, proc, nxttime);
3004b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		break;
3014b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	case LEAVECRIT:
3024b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		critfree = TRUE;
303354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		addevent(ATBARRIER, proc, global_time);
304354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if ((p = getwaiting()) != 0) {
305354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			nxttime = global_time;
306354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			addevent(ENTERCRIT, p, nxttime);
3074b264476cb3f10b994b39e4b61cca0594ea79279robbiew		}
3084b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		break;
3094b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	case ATBARRIER:
3104b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		barcnt++;
311354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (barcnt == nproc) {
312354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			nxttime = global_time;
313354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			for (i = 1; i <= nproc; i++) {
314354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				nxttime += dtspinoff();
315354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				addevent(ENTERWORK, i, nxttime);
3164b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper			}
317354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			barcnt = 0;
3184b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper			ncycle++;
3194b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		}
3204b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		break;
3214b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	case ENTERWORK:
322354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		nxttime = global_time + dtwork();
323354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (ncycle < ncycmax)
324354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			addevent(LEAVEWORK, proc, nxttime);
3254b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		break;
3264b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	case LEAVEWORK:
327354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		addevent(TRYCRIT, proc, global_time);
3284b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		break;
3294b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	default:
3304b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		tst_brkm(TBROK, NULL, "Illegal event");
3314b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper		break;
3324b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	}
333354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return (0);
334bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
335bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
336354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int alternator = 1;
337bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiewstatic double mean;
338bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiewstatic double stdev;
339354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic double u1, u2;
340bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiewstatic double twopi;
341bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
342829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic void gaussinit(double m, double s)
343bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
344354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	mean = m;
345354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	stdev = s;
346354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	twopi = 2. * acos((double)-1.0);
3474b264476cb3f10b994b39e4b61cca0594ea79279robbiew	u1 = twopi / 400.0;
3484b264476cb3f10b994b39e4b61cca0594ea79279robbiew	u2 = twopi / 500.0;
349bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
3502c28215423293e443469a07ae7011135d058b671Garrett Cooper
351829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerstatic double gauss(void)
352bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew{
353354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	double x1, x2;
3544b264476cb3f10b994b39e4b61cca0594ea79279robbiew
3554b264476cb3f10b994b39e4b61cca0594ea79279robbiew	gcount++;
3564b264476cb3f10b994b39e4b61cca0594ea79279robbiew
3574b264476cb3f10b994b39e4b61cca0594ea79279robbiew	u1 += u2;
3584b264476cb3f10b994b39e4b61cca0594ea79279robbiew	if (u1 > 0.99)
3594b264476cb3f10b994b39e4b61cca0594ea79279robbiew		u1 = twopi / 500.0;
3604b264476cb3f10b994b39e4b61cca0594ea79279robbiew	u2 += u1;
3614b264476cb3f10b994b39e4b61cca0594ea79279robbiew	if (u2 > 0.99)
3624b264476cb3f10b994b39e4b61cca0594ea79279robbiew		u2 = twopi / 400.0;
3634b264476cb3f10b994b39e4b61cca0594ea79279robbiew
364354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (alternator == 1) {
3654b264476cb3f10b994b39e4b61cca0594ea79279robbiew		alternator = -1;
366354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		x1 = sqrt(-2.0 * log(u1)) * cos(twopi * u2);
367354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return (mean + stdev * x1);
3684b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	} else {
3694b264476cb3f10b994b39e4b61cca0594ea79279robbiew		alternator = 1;
370354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		x2 = sqrt(-2.0 * log(u1)) * sin(twopi * u2);
371354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		return (mean + stdev * x2);
3724b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper	}
373ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
374