Subject: port-mips/29698: floating point context not saved in pthread/mips
To: None <port-mips-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: Ignatios Souvatzis <ignatios@sinus.cs.uni-bonn.de>
List: netbsd-bugs
Date: 03/15/2005 14:35:00
Note: There was a bad value `' for the field `Class'.
It was set to the default value of `sw-bug'.
>Number: 29698
>Category: port-mips
>Synopsis: floating context not saved in pthread/mips
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-mips-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Mar 15 14:35:00 +0000 2005
>Originator: ignatios@sinus.cs.uni-bonn.de
>Release: NetBSD 2.99.14
>Organization:
computer science department, university of Bonn, Germany
>Environment:
NetBSD tequila-sunrise.duskware.de 2.99.14 NetBSD 2.99.14 (TEQUILA) #0:
Fri Jan 14 09:54:37 CET 2005
martin@night-porter.duskware.de:/usr/src/sys/arch/sgimips/compile/TEQUILA
sgimips
>Description:
Running part of the regression test for context switches from the SR
library, roughly translated to using pthread only, shows wrong FP results.
> ===== checking floating point =====
> mul3...stirring...returning
> mul3...stirring...returning
> mul3...stirring...returning
> mul3...stirring...returning
> oops -- product returned was 0.97504285672921098271
The expected result is 223092870.
(cstest.c shows wrong FP results, too, but I wanted a non-SR program to
demonstrate them to avoid being accused of abusing libpthread internals.)
>How-To-Repeat:
Compile this code (cc -o threadtest threadtest.c -lpthread -lm),
then run it.
#include <stdio.h>
#include <math.h>
#include <pthread.h>
double mul3(double, double, double, pthread_cond_t *);
void *stir(void *);
void *bar(void *);
pthread_cond_t s2, s5;
pthread_mutex_t m2, m5;
pthread_t thread2, thread5;
pthread_barrier_t startup;
int
main() {
int rc;
rc = pthread_mutex_init(&m2, 0);
if (rc)
err("pthread_mutex_init");
rc = pthread_mutex_init(&m5, 0);
if (rc)
err("pthread_mutex_init");
rc = pthread_cond_init(&s2, 0);
if (rc)
err("pthread_cond_init");
rc = pthread_cond_init(&s5, 0);
if (rc)
err("pthread_cond_init");
rc = pthread_create(&thread5, 0, stir, 0);
if (rc)
err("pthread_create");
rc = pthread_barrier_init(&startup, 0, 2);
if (rc)
err("pthread_barrier_init");
pthread_barrier_wait(&startup);
pthread_join(thread2, 0);
exit(0);
}
double
mul3(double x, double y, double z, pthread_cond_t *ctx) {
printf("mul3...");
pthread_cond_signal(&s5);
pthread_cond_wait(ctx,&m2);
printf("returning\n");
return x*y*z;
}
void *
stir(void *arg) {
double x = 1.7, y = 3.2, z = 2.4;
int rc;
pthread_mutex_lock(&m5);
rc = pthread_create(&thread2, 0, bar, 0);
if (rc)
err("pthread_create");
for (;;) {
pthread_cond_wait(&s5,&m5);
printf("stirring...");
x = sin ((y = cos (x + y + .4)) - (z = cos (x + z + .6)));
pthread_cond_signal(&s2);
}
}
void *
bar(void *arg) {
double d;
pthread_barrier_wait(&startup);
pthread_mutex_lock(&m2);
puts ("===== checking floating point =====");
d = mul3 (mul3 (2., 3., 5., &s2), mul3 (7., 11., 13., &s2),
mul3 (17., 19., 23., &s2), &s2);
if (d != 223092870.)
printf ("oops -- product returned was %.20g\n", d);
return(0);
}
>Fix:
Idea: save/restore fp regs in lib/libpthread/arch/mips/