NetBSD-5.0.2/regress/lib/libpthread/fpu/fpu.c
/* $NetBSD: fpu.c,v 1.2 2005/12/02 16:44:54 is Exp $ */
/*
* This is adapted from part of csw/cstest of the MPD implementation by
* the University of Arizona CS department (http://www.cs.arizona.edu/sr/)
* which is in the public domain:
*
* "The MPD system is in the public domain and you may use and distribute it
* as you wish. We ask that you retain credits referencing the University
* of Arizona and that you identify any changes you make.
*
* We can't provide a warranty with MPD; it's up to you to determine its
* suitability and reliability for your needs. We would like to hear of
* any problems you encounter but we cannot promise a timely correction."
*
* It was changed to use pthread_create() and sched_yield() instead of
* the internal MPD context switching primitives by Ignatios Souvatzis
* <is@netbsd.org>.
*/
#include <math.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define N_RECURSE 10
double mul3(double, double, double);
void *stir(void *);
void *bar(void *);
void dotest(void);
#define RCTEST(code, mess) if (rc) {fprintf(stderr, "%s\n", mess); exit(1);}
#define YIELD() if (sched_yield()) {fprintf(stderr, "sched_yield"); exit(1);}
#define LOCK(l) if (pthread_mutex_lock(l)) {fprintf(stderr, "lock"); exit(1);}
#define UNLOCK(l) if (pthread_mutex_unlock(l)) {fprintf(stderr, "unlock"); exit(1);}
int recursion_depth = 0;
pthread_mutex_t recursion_depth_lock;
pthread_t s5;
double stirseed[] = {1.7, 3.2, 2.4};
int verbose = 0;
#define Dprintf(x) if(verbose) printf(x)
int
main(int argc, char *argv[]) {
int rc;
printf("Testing threaded floating point computations...");
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'v') {
verbose = 1;
printf("\n");
}
rc = pthread_mutex_init(&recursion_depth_lock, 0);
if (0 != rc) {
fprintf(stderr, "pthread_mutex_init");
exit(1);
}
pthread_create(&s5, 0, stir, stirseed);
dotest();
fprintf(stderr, "\n exiting from main\n");
exit(1);
}
void *
stir(void *p) {
double *q = (double *)p;
double x = *q++;
double y = *q++;
double z = *q++;
for (;;) {
Dprintf("stirring...");
x = sin ((y = cos (x + y + .4)) - (z = cos (x + z + .6)));
YIELD();
}
}
double mul3(double x, double y, double z) {
Dprintf("mul3...");
YIELD();
Dprintf("returning...\n");
return x * y * z;
}
void *bar(void *p) {
double d;
int rc;
d = mul3(mul3(2., 3., 5.), mul3(7., 11., 13.),
mul3(17., 19., 23.));
if (d != 223092870.) {
printf("\noops - product returned was %.20g\nFAILED\n", d);
exit(1);
}
LOCK(&recursion_depth_lock);
rc = recursion_depth++;
UNLOCK(&recursion_depth_lock);
if (rc < N_RECURSE) {
dotest();
}
Dprintf("\n");
printf("OK\n");
exit(0);
}
void dotest() {
pthread_t s2;
Dprintf("recursing...");
pthread_create(&s2, 0, bar, 0);
sleep(20); /* XXX must be long enough for our slowest machine */
}