1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (c) 2004, Bull S.A..  All rights reserved.
30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Created by: Sebastien Decugis
40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This program is free software; you can redistribute it and/or modify it
60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * under the terms of version 2 of the GNU General Public License as
70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * published by the Free Software Foundation.
80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This program is distributed in the hope that it would be useful, but
100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * WITHOUT ANY WARRANTY; without even the implied warranty of
110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * You should have received a copy of the GNU General Public License along
140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * with this program; if not, write the Free Software Foundation, Inc.,
150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This file is a scalability test for the pthread_cond_timedwait function.
190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * It aims to measure the time between end of timeout and actual wakeup
210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * with different factors.
220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * The steps are:
240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * -*- Number of threads waiting on the conditionnal variable
250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *     -> for an increaing number of threads,
260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *        -> create the other threads which will do a pthread_cond_wait on the same cond/mutex
270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *        -> When the threads are waiting, create one thread which will measure the time
280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *        -> once the timeout has expired and the measure is done, broadcast the condition.
290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *     -> do each measure 10 times (with different attributes i.e.)
300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * -*- other possible influencial parameters
320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *     -> To be defined.
330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */
360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define _POSIX_C_SOURCE 200112L
370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef WITHOUT_XOPEN
390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define _XOPEN_SOURCE 600
400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/********************************************************************************************/
430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/****************************** standard includes *****************************************/
440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/********************************************************************************************/
450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <pthread.h>
460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdarg.h>
470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h>
480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h>
490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <unistd.h>
500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <time.h>
520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h>
530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <math.h>
540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/********************************************************************************************/
560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/******************************   Test framework   *****************************************/
570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/********************************************************************************************/
580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "testfrmw.h"
590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "testfrmw.c"
600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* This header is responsible for defining the following macros:
610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  * UNRESOLVED(ret, descr);
620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  *    where descr is a description of the error and ret is an int (error code for example)
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  * FAILED(descr);
640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  *    where descr is a short text saying why the test has failed.
650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  * PASSED();
661a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee  *    No parameter.
671a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee  *
681a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee  * Both three macros shall terminate the calling process.
691a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee  * The testcase shall not terminate in any other maneer.
70c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh  *
71c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh  * The other file defines the functions
72c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh  * void output_init()
73c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh  * void output(char * string, ...)
74c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh  *
75c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh  * Those may be used to output information.
76c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh  */
770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/********************************************************************************************/
79f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh/********************************** Configuration ******************************************/
800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/********************************************************************************************/
810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef SCALABILITY_FACTOR
82c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define SCALABILITY_FACTOR 1
83c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
84c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef VERBOSE
85c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define VERBOSE 1
86c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
87c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
88c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef WITHOUT_ALTCLK
89c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define USE_ALTCLK		/* make tests with MONOTONIC CLOCK if supported */
90c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
91c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
92c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define MES_TIMEOUT  (1000000)	/* ns, offset for the pthread_cond_timedwait call */
93c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
94c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef PLOT_OUTPUT
95c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#undef VERBOSE
96c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define VERBOSE 0
97c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
98c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
99c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh// #define USE_CANCEL  /* Will cancel the threads instead of signaling the cond */#define
100c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
101c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/********************************************************************************************/
102c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/***********************************    Test case   *****************************************/
103c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/********************************************************************************************/
104c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
105c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehlong altclk_ok, pshared_ok;
106c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
107c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehtypedef struct {
108c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	pthread_cond_t *cnd;
109c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	pthread_mutex_t *mtx;
110c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int *predicate;
111c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int *tnum;
112c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh} test_t;
113c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
114c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstruct {
115c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int mutex_type;
116c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int pshared;
117c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	clockid_t cid;
118c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	char *desc;
119c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh} test_scenar[] = {
120c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	{
121c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	PTHREAD_MUTEX_DEFAULT, PTHREAD_PROCESS_PRIVATE, CLOCK_REALTIME,
122c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    "Default"}
123c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
124c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	PTHREAD_MUTEX_DEFAULT, PTHREAD_PROCESS_SHARED, CLOCK_REALTIME,
125c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    "PShared"}
126c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef WITHOUT_XOPEN
127c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
128c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	PTHREAD_MUTEX_NORMAL, PTHREAD_PROCESS_PRIVATE, CLOCK_REALTIME,
129c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    "Normal"}
130c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
131c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	PTHREAD_MUTEX_NORMAL, PTHREAD_PROCESS_SHARED, CLOCK_REALTIME,
132c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    "Normal+PShared"}
133c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PTHREAD_MUTEX_ERRORCHECK, PTHREAD_PROCESS_PRIVATE,
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    CLOCK_REALTIME, "Errorcheck"}
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	, {
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PTHREAD_MUTEX_ERRORCHECK, PTHREAD_PROCESS_SHARED,
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    CLOCK_REALTIME, "Errorcheck+PShared"}
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	, {
140c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	PTHREAD_MUTEX_RECURSIVE, PTHREAD_PROCESS_PRIVATE,
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    CLOCK_REALTIME, "Recursive"}
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	, {
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PTHREAD_MUTEX_RECURSIVE, PTHREAD_PROCESS_SHARED, CLOCK_REALTIME,
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Recursive+PShared"}
145c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef USE_ALTCLK
147c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
148c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	PTHREAD_MUTEX_DEFAULT, PTHREAD_PROCESS_PRIVATE, CLOCK_MONOTONIC,
149c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    "Monotonic"}
150c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PTHREAD_MUTEX_DEFAULT, PTHREAD_PROCESS_SHARED, CLOCK_MONOTONIC,
152c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    "PShared+Monotonic"}
153c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef WITHOUT_XOPEN
154c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
155c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	PTHREAD_MUTEX_NORMAL, PTHREAD_PROCESS_PRIVATE, CLOCK_MONOTONIC,
156c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    "Normal+Monotonic"}
157c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
158c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	PTHREAD_MUTEX_NORMAL, PTHREAD_PROCESS_SHARED, CLOCK_MONOTONIC,
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Normal+PShared+Monotonic"}
160c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PTHREAD_MUTEX_ERRORCHECK, PTHREAD_PROCESS_PRIVATE,
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    CLOCK_MONOTONIC, "Errorcheck+Monotonic"}
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	, {
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PTHREAD_MUTEX_ERRORCHECK, PTHREAD_PROCESS_SHARED,
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    CLOCK_MONOTONIC, "Errorcheck+PShared+Monotonic"}
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	, {
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PTHREAD_MUTEX_RECURSIVE, PTHREAD_PROCESS_PRIVATE,
168c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    CLOCK_MONOTONIC, "Recursive+Monotonic"}
169c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	, {
170c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	PTHREAD_MUTEX_RECURSIVE, PTHREAD_PROCESS_SHARED,
171c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    CLOCK_MONOTONIC, "Recursive+PShared+Monotonic"}
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
173c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define NSCENAR (sizeof(test_scenar) / sizeof(test_scenar[0]))
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpthread_attr_t ta;
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* The next structure is used to save the tests measures */
181c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehtypedef struct __mes_t {
182c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int nthreads;
183c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	long _data[NSCENAR];	/* As we store µsec values, a long type should be amply enough. */
184c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct __mes_t *next;
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} mes_t;
186c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/**** do_measure
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function will do a timedwait on the cond cnd after locking mtx.
189c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * Once the timedwait times out, it will read the clock cid then
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * compute the difference and put it into ts.
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function must be called once test is ready, as the timeout will be very short. */
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid do_measure(pthread_mutex_t * mtx, pthread_cond_t * cnd, clockid_t cid,
193c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct timespec *ts)
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ret, rc;
196c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
197c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct timespec ts_cnd, ts_clk;
198c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
199c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* lock the mutex */
200c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ret = pthread_mutex_lock(mtx);
201c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (ret != 0) {
202c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		UNRESOLVED(ret, "Unable to lock mutex");
203c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
204c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
205c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* Prepare the timeout parameter */
206c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ret = clock_gettime(cid, &ts_cnd);
207c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (ret != 0) {
208c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		UNRESOLVED(errno, "Unable to read clock");
209c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
210c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
211c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ts_cnd.tv_nsec += MES_TIMEOUT;
212c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	while (ts_cnd.tv_nsec >= 1000000000) {
213c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		ts_cnd.tv_nsec -= 1000000000;
214c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		ts_cnd.tv_sec++;
215c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
217c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* Do the timedwait */
218c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	do {
219c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		rc = pthread_cond_timedwait(cnd, mtx, &ts_cnd);
220c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* Re-read the clock as soon as possible */
221c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		ret = clock_gettime(cid, &ts_clk);
222c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (ret != 0) {
223c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			UNRESOLVED(errno, "Unable to read clock");
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
225c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
226c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	while (rc == 0);
227c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (rc != ETIMEDOUT) {
228c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		UNRESOLVED(rc,
229c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			   "Timedwait returned an unexpected error (expected ETIMEDOUT)");
230c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
231c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
232c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* Compute the difference time */
233c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ts->tv_sec = ts_clk.tv_sec - ts_cnd.tv_sec;
234c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ts->tv_nsec = ts_clk.tv_nsec - ts_cnd.tv_nsec;
235c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (ts->tv_nsec < 0) {
236c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		ts->tv_nsec += 1000000000;
237c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		ts->tv_sec -= 1;
238c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
239c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
240c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (ts->tv_sec < 0) {
241c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		FAILED
242c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    ("The function returned from wait with a timeout before the time has passed\n");
243c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
244c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
245c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* unlock the mutex */
246c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ret = pthread_mutex_unlock(mtx);
247c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (ret != 0) {
248c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		UNRESOLVED(ret, "Unable to unlock mutex");
249c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
250c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
251c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return;
252c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}
253c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
254c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid *waiter(void *arg)
255c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
256c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	test_t *dt = (test_t *) arg;
257c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ret;
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
260c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	ret = pthread_mutex_lock(dt->mtx);
261c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	if (ret != 0) {
262c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh		UNRESOLVED(ret, "Mutex lock failed in waiter");
263c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
264c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh#ifdef USE_CANCEL
265c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	pthread_cleanup_push((void *)pthread_mutex_unlock, (void *)(dt->mtx));
266c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
2671a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee
2681a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee	/* This thread is ready to wait */
2691a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee	*(dt->tnum) += 1;
2701a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee
271c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	do {
272c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh		ret = pthread_cond_wait(dt->cnd, dt->mtx);
273c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	}
274c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	while ((ret == 0) && (*(dt->predicate) == 0));
275c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	if (ret != 0) {
276c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh		UNRESOLVED(ret, "pthread_cond_wait failed in waiter");
277c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	}
278c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh#ifdef USE_CANCEL
279c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	pthread_cleanup_pop(0);	/* We could put 1 and avoid the next line, but we would miss the return code */
280c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh#endif
281c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
282c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ret = pthread_mutex_unlock(dt->mtx);
283c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	if (ret != 0) {
284c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh		UNRESOLVED(ret, "Mutex unlock failed in waiter");
285c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	}
286c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
287c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	return NULL;
288c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh}
289c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
290c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh/**** do_threads_test
291c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * This function is responsible for all the testing with a given # of threads
292c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh *  nthreads is the amount of threads to create.
293c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh * the return value is:
294a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh *  < 0 if function was not able to create enough threads.
295c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh *  cumulated # of nanoseconds otherwise.
296c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh */
297c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yehlong do_threads_test(int nthreads, mes_t * measure)
298c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh{
299c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	int ret;
300c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
301c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	int scal, i, j;
302c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
303c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	pthread_t *th;
304c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
305c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	int s;
306c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	pthread_mutexattr_t ma;
307c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	pthread_condattr_t ca;
308c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
309c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	pthread_cond_t cnd;
310c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	pthread_mutex_t mtx;
311c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	int predicate;
312c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	int tnum;
313c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
314c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	test_t td;
315a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh
316a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh	struct timespec ts, ts_cumul;
317a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh
318a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh	td.mtx = &mtx;
319a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh	td.cnd = &cnd;
320a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh	td.predicate = &predicate;
321a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh	td.tnum = &tnum;
322a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh
323c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	/* Allocate space for the threads structures */
324c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	th = (pthread_t *) calloc(nthreads, sizeof(pthread_t));
325c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	if (th == NULL) {
326a6239141a335940e5f665e3f0dc99c9c5cad8966Chia-chi Yeh		UNRESOLVED(errno, "Not enough memory for thread storage");
327c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh	}
328c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh#ifdef PLOT_OUTPUT
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("%d", nthreads);
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* For each test scenario (mutex and cond attributes) */
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (s = 0; s < NSCENAR; s++) {
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Initialize the attributes */
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ret = pthread_mutexattr_init(&ma);
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ret != 0) {
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			UNRESOLVED(ret,
3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				   "Unable to initialize mutex attribute object");
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ret = pthread_condattr_init(&ca);
3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ret != 0) {
3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			UNRESOLVED(ret,
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				   "Unable to initialize cond attribute object");
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
346c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* Set the attributes according to the scenar and the impl capabilities */
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ret = pthread_mutexattr_settype(&ma, test_scenar[s].mutex_type);
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ret != 0) {
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			UNRESOLVED(ret, "Unable to set mutex type");
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3511a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee
3521a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee		if (pshared_ok > 0) {
3531a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee			ret =
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    pthread_mutexattr_setpshared(&ma,
3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							 test_scenar[s].
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							 pshared);
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				UNRESOLVED(ret,
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					   "Unable to set mutex process-shared");
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ret =
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    pthread_condattr_setpshared(&ca,
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							test_scenar[s].pshared);
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				UNRESOLVED(ret,
3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					   "Unable to set cond process-shared");
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef USE_ALTCLK
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (altclk_ok > 0) {
3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ret =
3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    pthread_condattr_setclock(&ca, test_scenar[s].cid);
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				UNRESOLVED(ret, "Unable to set clock for cond");
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ts_cumul.tv_sec = 0;
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ts_cumul.tv_nsec = 0;
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("Starting case %s\n", test_scenar[s].desc);
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (scal = 0; scal < 5 * SCALABILITY_FACTOR; scal++) {
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Initialize the mutex, the cond, and other data */
3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ret = pthread_mutex_init(&mtx, &ma);
3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				UNRESOLVED(ret, "Mutex init failed");
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ret = pthread_cond_init(&cnd, &ca);
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
396c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				UNRESOLVED(ret, "Cond init failed");
397c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			predicate = 0;
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tnum = 0;
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Create the waiter threads */
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (i = 0; i < nthreads; i++) {
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ret =
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    pthread_create(&th[i], &ta, waiter,
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						   (void *)&td);
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ret != 0) {	/* We reached the limits */
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					output
410c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					    ("Limit reached with %i threads\n",
411c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					     i);
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef USE_CANCEL
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					for (j = i - 1; j >= 0; j--) {
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						ret = pthread_cancel(th[j]);
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						if (ret != 0) {
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							UNRESOLVED(ret,
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang								   "Unable to cancel a thread");
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						}
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					}
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					predicate = 1;
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					ret = pthread_cond_broadcast(&cnd);
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (ret != 0) {
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						UNRESOLVED(ret,
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							   "Unable to broadcast the condition");
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					}
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					for (j = i - 1; j >= 0; j--) {
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						ret = pthread_join(th[j], NULL);
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						if (ret != 0) {
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							UNRESOLVED(ret,
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang								   "Unable to join a canceled thread");
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						}
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					}
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					free(th);
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* All waiter threads are created now */
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 5
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			output("%i waiter threads created successfully\n", i);
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
444c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ret = pthread_mutex_lock(&mtx);
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				UNRESOLVED(ret, "Unable to lock mutex");
4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Wait for all threads be waiting */
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while (tnum < nthreads) {
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ret = pthread_mutex_unlock(&mtx);
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ret != 0) {
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					UNRESOLVED(ret, "Mutex unlock failed");
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sched_yield();
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ret = pthread_mutex_lock(&mtx);
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ret != 0) {
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					UNRESOLVED(ret, "Mutex lock failed");
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
463c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
464c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* All threads are now waiting - we do the measure */
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ret = pthread_mutex_unlock(&mtx);
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				UNRESOLVED(ret, "Mutex unlock failed");
470c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 5
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			output("%i waiter threads are waiting; start measure\n",
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			       tnum);
4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			do_measure(&mtx, &cnd, test_scenar[s].cid, &ts);
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 5
4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			output("Measure for %s returned %d.%09d\n",
4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			       test_scenar[s].desc, ts.tv_sec, ts.tv_nsec);
481c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
482c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ts_cumul.tv_sec += ts.tv_sec;
4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ts_cumul.tv_nsec += ts.tv_nsec;
4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ts_cumul.tv_nsec >= 1000000000) {
4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ts_cumul.tv_nsec -= 1000000000;
4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ts_cumul.tv_sec += 1;
488c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* We can release the threads */
4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			predicate = 1;
4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ret = pthread_cond_broadcast(&cnd);
4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				UNRESOLVED(ret,
4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					   "Unable to broadcast the condition");
4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 5
4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			output("Joining the waiters...\n");
499c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
500c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* We will join every threads */
5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (i = 0; i < nthreads; i++) {
5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ret = pthread_join(th[i], NULL);
5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ret != 0) {
5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					UNRESOLVED(ret,
506c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						   "Unable to join a thread");
5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Destroy everything */
5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ret = pthread_mutex_destroy(&mtx);
5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				UNRESOLVED(ret, "Unable to destroy mutex");
5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
517c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			ret = pthread_cond_destroy(&cnd);
5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ret != 0) {
5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				UNRESOLVED(ret, "Unable to destroy cond");
5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef PLOT_OUTPUT
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output(" %d.%09d", ts_cumul.tv_sec, ts_cumul.tv_nsec);
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		measure->_data[s] = ts_cumul.tv_sec * 1000000 + (ts_cumul.tv_nsec / 1000);	/* We reduce precision */
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Destroy the mutex attributes */
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ret = pthread_mutexattr_destroy(&ma);
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ret != 0) {
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			UNRESOLVED(ret, "Unable to destroy mutex attribute");
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ret = pthread_condattr_destroy(&ca);
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ret != 0) {
537c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			UNRESOLVED(ret, "Unable to destroy cond attribute");
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Free the memory */
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free(th);
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 2
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("%5d threads; %d.%09d s (%i loops)\n", nthreads, ts_cumul.tv_sec,
546c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	       ts_cumul.tv_nsec, scal);
547c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef PLOT_OUTPUT
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("\n");
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ts_cumul.tv_sec * 1000000000 + ts_cumul.tv_nsec;
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Forward declaration */
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint parse_measure(mes_t * measures);
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Main
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint main(int argc, char *argv[])
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ret, nth;
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long dur;
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Initialize the measure list */
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mes_t sentinel;
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mes_t *m_cur, *m_tmp;
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	m_cur = &sentinel;
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	m_cur->next = NULL;
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Initialize the output */
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output_init();
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Test machine capabilities */
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* -> clockid_t; pshared; ... */
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	altclk_ok = sysconf(_SC_CLOCK_SELECTION);
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (altclk_ok > 0)
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		altclk_ok = sysconf(_SC_MONOTONIC_CLOCK);
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef USE_ALTCLK
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (altclk_ok > 0)
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    ("Implementation supports the MONOTONIC CLOCK but option is disabled in test.\n");
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pshared_ok = sysconf(_SC_THREAD_PROCESS_SHARED);
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 0
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("Test starting\n");
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output(" Process-shared primitive %s be tested\n",
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       (pshared_ok > 0) ? "will" : "won't");
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output(" Alternative clock for cond %s be tested\n",
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       (altclk_ok > 0) ? "will" : "won't");
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Prepare thread attribute */
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = pthread_attr_init(&ta);
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret != 0) {
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		UNRESOLVED(ret, "Unable to initialize thread attributes");
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = pthread_attr_setstacksize(&ta, sysconf(_SC_THREAD_STACK_MIN));
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret != 0) {
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		UNRESOLVED(ret, "Unable to set stack size to minimum value");
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef PLOT_OUTPUT
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("# COLUMNS %d #threads", NSCENAR + 1);
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (nth = 0; nth < NSCENAR; nth++)
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output(" %s", test_scenar[nth].desc);
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("\n");
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Do the testing */
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	nth = 0;
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	do {
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		nth += 100 * SCALABILITY_FACTOR;
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Create a new measure item */
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		m_tmp = malloc(sizeof(mes_t));
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (m_tmp == NULL) {
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			UNRESOLVED(errno,
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				   "Unable to alloc memory for measure saving");
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		m_tmp->nthreads = nth;
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		m_tmp->next = NULL;
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Run the test */
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dur = do_threads_test(nth, m_tmp);
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* If test was success, add this measure to the list. Otherwise, free the mem */
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (dur >= 0) {
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			m_cur->next = m_tmp;
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			m_cur = m_tmp;
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			free(m_tmp);
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (dur >= 0);
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* We will now parse the results to determine if the measure is ~ constant or is growing. */
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = parse_measure(&sentinel);
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Free the memory from the list */
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	m_cur = sentinel.next;
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (m_cur != NULL) {
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		m_tmp = m_cur;
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		m_cur = m_tmp->next;
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free(m_tmp);
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret != 0) {
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		FAILED("This function is not scalable");
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 0
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("The function is scalable\n");
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PASSED;
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/***
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * The next function will seek for the better model for each series of measurements.
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * The tested models are: -- X = # threads; Y = latency
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * -> Y = a;      -- Error is r1 = avg((Y - Yavg)²);
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * -> Y = aX + b; -- Error is r2 = avg((Y -aX -b)²);
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *                -- where a = avg ((X - Xavg)(Y - Yavg)) / avg((X - Xavg)²)
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *                --         Note: We will call _q = sum((X - Xavg) * (Y - Yavg));
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *                --                       and  _d = sum((X - Xavg)²);
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *                -- and   b = Yavg - a * Xavg
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * -> Y = c * X^a;-- Same as previous, but with log(Y) = a log(X) + b; and b = log(c). Error is r3
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * -> Y = exp(aX + b); -- log(Y) = aX + b. Error is r4
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * We compute each error factor (r1, r2, r3, r4) then search which is the smallest (with ponderation).
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * The function returns 0 when r1 is the best for all cases (latency is constant) and !0 otherwise.
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct row {
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long X;			/* the X values -- copied from function argument */
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long Y[NSCENAR];	/* the Y values -- copied from function argument */
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long _x;		/* Value X - Xavg */
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long _y[NSCENAR];	/* Value Y - Yavg */
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	double LnX;		/* Natural logarithm of X values */
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	double LnY[NSCENAR];	/* Natural logarithm of Y values */
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	double _lnx;		/* Value LnX - LnXavg */
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	double _lny[NSCENAR];	/* Value LnY - LnYavg */
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint parse_measure(mes_t * measures)
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ret, i, r;
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mes_t *cur;
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	double Xavg, Yavg[NSCENAR];
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	double LnXavg, LnYavg[NSCENAR];
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int N;
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	double r1[NSCENAR], r2[NSCENAR], r3[NSCENAR], r4[NSCENAR];
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Some more intermediate vars */
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long double _q[3][NSCENAR];
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long double _d[3][NSCENAR];
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long double t;		/* temp value */
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct row *Table = NULL;
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Initialize the datas */
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	Xavg = 0.0;
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	LnXavg = 0.0;
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < NSCENAR; i++) {
715c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		Yavg[i] = 0.0;
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		LnYavg[i] = 0.0;
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		r1[i] = 0.0;
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		r2[i] = 0.0;
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		r3[i] = 0.0;
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		r4[i] = 0.0;
7211a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee		_q[0][i] = 0.0;
7221a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee		_q[1][i] = 0.0;
7231a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee		_q[2][i] = 0.0;
7241a2c5e916d91b6efe0d57595b7b783dfdc15ad7dRobin Lee		_d[0][i] = 0.0;
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		_d[1][i] = 0.0;
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		_d[2][i] = 0.0;
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	N = 0;
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cur = measures;
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("Data analysis starting\n");
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* We start with reading the list to find:
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * -> number of elements, to assign an array
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * -> average values
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (cur->next != NULL) {
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cur = cur->next;
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		N++;
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		Xavg += (double)cur->nthreads;
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		LnXavg += log((double)cur->nthreads);
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (i = 0; i < NSCENAR; i++) {
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			Yavg[i] += (double)cur->_data[i];
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			LnYavg[i] += log((double)cur->_data[i]);
7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* We have the sum; we can divide to obtain the average values */
754c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	Xavg /= N;
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	LnXavg /= N;
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < NSCENAR; i++) {
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		Yavg[i] /= N;
7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		LnYavg[i] /= N;
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output(" Found %d rows and %d columns\n", N, NSCENAR);
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* We will now alloc the array ... */
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	Table = calloc(N, sizeof(struct row));
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (Table == NULL) {
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		UNRESOLVED(errno, "Unable to alloc space for results parsing");
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ... and fill it */
7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	N = 0;
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cur = measures;
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (cur->next != NULL) {
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cur = cur->next;
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		Table[N].X = (long)cur->nthreads;
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		Table[N]._x = Table[N].X - Xavg;
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		Table[N].LnX = log((double)cur->nthreads);
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		Table[N]._lnx = Table[N].LnX - LnXavg;
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (i = 0; i < NSCENAR; i++) {
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			Table[N].Y[i] = cur->_data[i];
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			Table[N]._y[i] = Table[N].Y[i] - Yavg[i];
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			Table[N].LnY[i] = log((double)cur->_data[i]);
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			Table[N]._lny[i] = Table[N].LnY[i] - LnYavg[i];
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		N++;
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* We won't need the list anymore -- we'll work with the array which should be faster. */
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output(" Data was stored in an array.\n");
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* We need to read the full array at least twice to compute all the error factors */
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* In the first pass, we'll compute:
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * -> r1 for each scenar.
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * -> "a" factor for linear (0), power (1) and exponential (2) approximations -- with using the _d and _q vars.
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("Starting first pass...\n");
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (r = 0; r < N; r++) {
8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (i = 0; i < NSCENAR; i++) {
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			r1[i] +=
8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    ((double)Table[r]._y[i] / N) *
8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (double)Table[r]._y[i];
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			_q[0][i] += Table[r]._y[i] * Table[r]._x;
8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			_d[0][i] += Table[r]._x * Table[r]._x;
8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			_q[1][i] += Table[r]._lny[i] * Table[r]._lnx;
8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			_d[1][i] += Table[r]._lnx * Table[r]._lnx;
818c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			_q[2][i] += Table[r]._lny[i] * Table[r]._x;
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			_d[2][i] += Table[r]._x * Table[r]._x;
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* First pass is terminated; a2 = _q[0]/_d[0]; a3 = _q[1]/_d[1]; a4 = _q[2]/_d[2] */
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* In the first pass, we'll compute:
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * -> r2, r3, r4 for each scenar.
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("Starting second pass...\n");
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (r = 0; r < N; r++) {
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (i = 0; i < NSCENAR; i++) {
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* r2 = avg((y - ax -b)²);  t = (y - ax - b) = (y - yavg) - a (x - xavg); */
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			t = (Table[r]._y[i] -
837c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			     ((_q[0][i] * Table[r]._x) / _d[0][i]));
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			r2[i] += t * t / N;
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* r3 = avg((y - c.x^a) ²);
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			   t = y - c * x ^ a
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			   = y - log (LnYavg - (_q[1]/_d[1]) * LnXavg) * x ^ (_q[1]/_d[1])
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			t = (Table[r].Y[i]
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     - (logl(LnYavg[i] - (_q[1][i] / _d[1][i]) * LnXavg)
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				* powl(Table[r].X, (_q[1][i] / _d[1][i]))
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     ));
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			r3[i] += t * t / N;
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* r4 = avg((y - exp(ax+b))²);
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			   t = y - exp(ax+b)
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			   = y - exp(_q[2]/_d[2] * x + (LnYavg - (_q[2]/_d[2] * Xavg)));
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			   = y - exp(_q[2]/_d[2] * (x - Xavg) + LnYavg);
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			t = (Table[r].Y[i]
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     - expl((_q[2][i] / _d[2][i]) * Table[r]._x +
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    LnYavg[i]));
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			r4[i] += t * t / N;
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	output("All computing terminated.\n");
8650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = 0;
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < NSCENAR; i++) {
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("\nScenario: %s\n", test_scenar[i].desc);
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("  Model: Y = k\n");
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("       k = %g\n", Yavg[i]);
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("    Divergence %g\n", r1[i]);
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("  Model: Y = a * X + b\n");
876c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		output("       a = %Lg\n", _q[0][i] / _d[0][i]);
877c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		output("       b = %Lg\n",
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       Yavg[i] - ((_q[0][i] / _d[0][i]) * Xavg));
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("    Divergence %g\n", r2[i]);
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("  Model: Y = c * X ^ a\n");
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("       a = %Lg\n", _q[1][i] / _d[1][i]);
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("       c = %Lg\n",
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       logl(LnYavg[i] - (_q[1][i] / _d[1][i]) * LnXavg));
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("    Divergence %g\n", r2[i]);
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("  Model: Y = exp(a * X + b)\n");
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("       a = %Lg\n", _q[2][i] / _d[2][i]);
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("       b = %Lg\n",
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       LnYavg[i] - ((_q[2][i] / _d[2][i]) * Xavg));
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		output("    Divergence %g\n", r2[i]);
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Compare r1 to other values, with some ponderations */
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((r1[i] > 1.1 * r2[i]) || (r1[i] > 1.2 * r3[i])
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    || (r1[i] > 1.3 * r4[i]))
8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ret++;
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if VERBOSE > 1
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			output(" Sanction: OK\n");
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* We need to free the array */
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free(Table);
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* We're done */
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ret;
9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang