Package: libc0.1
Version: 2.13-38+deb7u2
X-Debbugs-CC: jtaylor.deb...@googlemail.com , debian-...@lists.debian.org

On Sat, 6 Sep 2014, Julian Taylor wrote:
I encountered a weird issue on kfreebsd i386 using pthreads. It seems to
change the x87 fpu precision mode (bits 8 and 9 of the control word) in
threads compared to the master. In the master its set to extended
precision, in child threads it changes to double precision. This breaks
equality of e.g. python-numpy's threaded and serial random number generator.

Is this expected? it doesn't happen on linux i386.

The thread started in kernel have different default precision
in FreeBSD compared to Linux.

The initial value of precision is set-up before main() starts,
but not in each thread.

We should think about how it should be fixed.
The new thread should either inherit FPU control word from parent, or it should be created with the same value as original main().

Julian, please, could you verify behaviour of linux-i386 ?

Hint:

typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
#define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw))
#define _FPU_SETCW(cw) __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw))

test with values 0x037f, 0x027f, 0x007f

To reproduce use this simple file and gdb on fischer.debian.org:

$ cat test.c
#include <pthread.h>
#include <stdio.h>

void *thread_fun(void *x_void_ptr)
{
   printf("thread\n");
   return NULL;
}

int main()
{
   pthread_t thread;

   if(pthread_create(&thread, NULL, thread_fun, NULL)) {
       fprintf(stderr, "Error creating thread\n");
       return 1;
   }
   if(pthread_join(thread, NULL)) {
       fprintf(stderr, "Error joining thread\n");
       return 2;
   }
   return 0;

}

$ gcc test.c -g -pthreads

$ gdb ./a.out

(gdb) break main
Breakpoint 1 at 0x8048589: file test.c, line 14.
(gdb) break thread_fun
Breakpoint 2 at 0x8048561: file test.c, line 6.
(gdb) r
Starting program: /home/jtaylor/a.out

Breakpoint 1, main () at test.c:14
14          if(pthread_create(&thread, NULL, thread_fun, NULL)) {
(gdb) p $fctrl
$1 = 4991
(gdb) c
Continuing.

Breakpoint 2, thread_fun (x_void_ptr=0x0) at test.c:6
6           printf("thread\n");
(gdb) p $fctrl
$2 = 4735


--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to