Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / regress / lib / libpthread / fpu / fpu.c
blobea02c45195aea44fc6eb6e465380c6eabe4dc2b1
1 /* $NetBSD: fpu.c,v 1.1 2005/12/01 16:03:36 is Exp $ */
3 /*
4 * This is adapted from part of csw/cstest of the MPD implementation by
5 * the University of Arizona CS department (http://www.cs.arizona.edu/sr/)
6 * which is in the public domain:
8 * "The MPD system is in the public domain and you may use and distribute it
9 * as you wish. We ask that you retain credits referencing the University
10 * of Arizona and that you identify any changes you make.
12 * We can't provide a warranty with MPD; it's up to you to determine its
13 * suitability and reliability for your needs. We would like to hear of
14 * any problems you encounter but we cannot promise a timely correction."
16 * It was changed to use pthread_create() and sched_yield() instead of
17 * the internal MPD context switching primitives by Ignatios Souvatzis
18 * <is@netbsd.org>.
21 #include <math.h>
22 #include <pthread.h>
23 #include <sched.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
28 #define N_RECURSE 10
30 double mul3(double, double, double);
31 void *stir(void *);
32 void *bar(void *);
33 void dotest(void);
35 #define RCTEST(code, mess) if (rc) {fprintf(stderr, "%s\n", mess); exit(1);}
36 #define YIELD() if (sched_yield()) {fprintf(stderr, "sched_yield"); exit(1);}
37 #define LOCK(l) if (pthread_mutex_lock(l)) {fprintf(stderr, "lock"); exit(1);}
38 #define UNLOCK(l) if (pthread_mutex_unlock(l)) {fprintf(stderr, "unlock"); exit(1);}
40 int recursion_depth = 0;
41 pthread_mutex_t recursion_depth_lock;
42 pthread_t s5;
43 double stirseed[] = {1.7, 3.2, 2.4};
44 int verbose = 0;
46 #define Dprintf(x) if(verbose) printf(x)
48 int
49 main(int argc, char *argv[]) {
51 int rc;
53 printf("Testing threaded floating point computations...");
54 if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'v') {
55 verbose = 1;
56 printf("\n");
58 rc = pthread_mutex_init(&recursion_depth_lock, 0);
59 if (0 != rc) {
60 fprintf(stderr, "pthread_mutex_init");
61 exit(1);
63 pthread_create(&s5, 0, stir, stirseed);
64 dotest();
66 fprintf(stderr, "\n exiting from main\n");
67 exit(1);
70 void *
71 stir(void *p) {
72 double *q = (double *)p;
73 double x = *q++;
74 double y = *q++;
75 double z = *q++;
76 for (;;) {
77 Dprintf("stirring...");
78 x = sin ((y = cos (x + y + .4)) - (z = cos (x + z + .6)));
79 YIELD();
83 double mul3(double x, double y, double z) {
84 Dprintf("mul3...");
85 YIELD();
86 Dprintf("returning...\n");
87 return x * y * z;
90 void *bar(void *p) {
91 double d;
92 int rc;
94 d = mul3(mul3(2., 3., 5.), mul3(7., 11., 13.),
95 mul3(17., 19., 23.));
97 if (d != 223092870.) {
98 printf("\noops - product returned was %.20g\nFAILED\n", d);
99 exit(1);
102 LOCK(&recursion_depth_lock);
103 rc = recursion_depth++;
104 UNLOCK(&recursion_depth_lock);
105 if (rc < N_RECURSE) {
106 dotest();
108 Dprintf("\n");
109 printf("OK\n");
110 exit(0);
113 void dotest() {
114 pthread_t s2;
115 Dprintf("recursing...");
116 pthread_create(&s2, 0, bar, 0);
117 sleep(20); /* XXX must be long enough for our slowest machine */