diff options
Diffstat (limited to 'mit-pthreads/tests/test_preemption_float.c')
-rw-r--r-- | mit-pthreads/tests/test_preemption_float.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/mit-pthreads/tests/test_preemption_float.c b/mit-pthreads/tests/test_preemption_float.c new file mode 100644 index 00000000000..e12192044c6 --- /dev/null +++ b/mit-pthreads/tests/test_preemption_float.c @@ -0,0 +1,98 @@ +/* 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 <pthread.h> +#include <math.h> +#include <stdio.h> + +int limit = 2; +int float_passed = 0; +int float_failed = 1; + +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) { */ + if (memcmp (&d2, &d1, 8)) { + pthread_exit(&float_failed); + } + } + } + pthread_exit(&float_passed); +} + +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) { */ + if (memcmp (&d2, &d1, 8)) { + pthread_exit(&float_failed); + } + } + } + pthread_exit(&float_passed); +} + +#define N 10 +int main () { + int i; + pthread_t thread[2]; + pthread_attr_t attr; + int *x, *y; + + pthread_init (); + pthread_attr_init(&attr); + pthread_attr_setfloatstate(&attr, PTHREAD_NOFLOAT); + + while(limit < 100000) { + pthread_create (&thread[0], &attr, trig_loop, 0); + pthread_create (&thread[1], &attr, log_loop, 0); + pthread_join(thread[0], (void **) &x); + pthread_join(thread[1], (void **) &y); + if ((*x == float_failed) || (*y == float_failed)) { + limit *= 4; + break; + } + limit *= 4; + } + if ((*x == float_passed) && (*y == float_passed)) { + printf("test_preemption_float INDETERMINATE\n"); + return(0); + } + pthread_create (&thread[0], NULL, trig_loop, 0); + pthread_create (&thread[1], NULL, log_loop, 0); + pthread_join(thread[0], (void **) &x); + pthread_join(thread[1], (void **) &y); + + if ((*x == float_failed) || (*y == float_failed)) { + printf("test_preemption_float FAILED\n"); + return(1); + } + printf("test_preemption_float PASSED\n"); + return(0); +} |