Floating point exceptions with -pthread
Daniel Eischen
deischen at freebsd.org
Wed May 4 08:06:36 PDT 2005
On Wed, 4 May 2005, Marc Olzheim wrote:
> On Tue, May 03, 2005 at 09:54:23AM -0400, Daniel Eischen wrote:
> > > Hi.
> > >
> > > I was wondering whether it was safe to use floating point calculations /
> > > libm functions with 5.4-STABLE's pthread library on HT+SMP. I keep
> > > getting floating point exceptions on places where they should not
> > > happen... :-(
> >
> > Yes, it should work fine. If you can verify the problem exists
> > (or doesn't) on -current, that might help. It sounds like FPU
> > context isn't getting saved/restored correctly in the kernel.
>
> Should I file a PR ?
Yes, it happens also on a UP system with a few month old -current.
Is there a similar test you can use that doesn't use floor()?
This one seems to work but doesn't use libm.
--
DE
-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
#include <err.h>
#include <stdlib.h>
#include <limits.h>
#include <inttypes.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *foo(void *);
typedef struct
{
int number;
int loops;
} arg_t;
/*
* Simple test case for the thread system. Start "n" threads,
* and join them afterwards.
*/
int
main( int argc, char** argv)
{
struct sched_param param;
pthread_t* threads;
pthread_attr_t attr;
arg_t* args;
void* ret;
int policy;
int n;
int i;
if (argc > 1) {
n = strtoimax(argv[1], NULL, 10);
printf("Using %d threads (parameter)\n", n);
} else {
n = 5;
printf("Using %d threads (default)\n", n);
}
// initialize random number generator
srandomdev();
threads = (pthread_t *)malloc(sizeof(pthread_t) * n);
args = (arg_t *)malloc(sizeof(arg_t) * n);
// start n threads
pthread_attr_init(&attr);
//pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
for (i = 0; i < n; i++) {
args[i].number = i;
if (pthread_create(&threads[i], &attr, foo, &args[i]) != 0) {
err(1, NULL);
}
}
pthread_getschedparam(pthread_self(), &policy, ¶m);
param.sched_priority++;
pthread_setschedparam(pthread_self(), policy, ¶m);
// join threads
for (i = 0; i < n; i++) {
if (pthread_join(threads[i], &ret) != 0) {
err(1, NULL);
}
printf("Joined bar %d, loops %d\n",
args[i].number, args[i].loops);
}
free(threads);
sleep(1);
return (0);
}
void *
foo(void *v)
{
arg_t *arg;
float a, b, c;
float d __unused;
int i;
int loops;
arg = (arg_t *)v;
printf("bar %d running\n", arg->number);
/* Simulate some CPU-intensive calculations. */
#if 1
while (1) {
#else
loops = 5000000;
for (i = 1; i < loops; i++) {
#endif
a = (float)i * ((float)random() / 11.0);
b = a * ((float)random() / 13.0);
c = b * ((float)random() / 17.0);
d = c * ((float)random() / 23.0);
}
arg->loops = loops;
//printf("bar %d, loops %d\n", arg->number, arg->loops);
return (NULL);
}
More information about the freebsd-threads
mailing list