/* Test to see if floating point state is being properly maintained
   for each thread.  Different threads doing floating point operations
   simultaneously should not interfere with one another.  This
   includes operations that might change some FPU flags, such as
   rounding modes, at least implicitly.  */

#include <stdio.h>
#include <math.h>
#include <pthread.h>

int limit = 1000000;

void *log_loop (void *x) {
  int i;
  double d, d1, d2;
  /* sleep (1); */
  for (i = 0; i < limit; i++) {
    d = 42.0;
    d = log (exp (d));
    d = (d + 39.0) / d;
    if (i == 0)
      d1 = d;
    else {
		d2 = d;
		d = sin(d);
		if (d2 != d1)
      		abort ();
	}
  }
}

void *trig_loop (void *x) {
  int i;
  double d, d1, d2;
  /* sleep (1);  */
  for (i = 0; i < limit; i++) {
    d = 35.0;
    d *= M_PI;
    d /= M_LN2;
    d = sin (d);
    d = cos (1 / d);
    if (i == 0)
      d1 = d;
    else {
		d2 = d;
		d = sin(d);
		if (d2 != d1)
      		abort ();
	}
  }
}

#define N 10
int main () {
  int i;
  pthread_t thread[N][2];
  void *x;

  pthread_init ();
  for (i = 0; i < N; i++) {
    pthread_create (&thread[i][0], 0, log_loop, 0);
    pthread_create (&thread[i][1], 0, trig_loop, 0);
  }
  for (i = 0; i < N; i++) {
    pthread_join (thread[i][0], 0);
    pthread_join (thread[i][1], 0);
  }
  return 0;
}
