This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
e_pow and reentrancy
- From: Simon Gee <simong at agile dot tv>
- To: libc-alpha at sources dot redhat dot com
- Date: Fri, 09 Aug 2002 11:15:45 +1000
- Subject: e_pow and reentrancy
- Organization: AgileTV Corporation Australia
Recently I've been running the LTP testsuite on a linux/mips platform
running glibc 2.2.4 and have been receiving incorrect results while
executing the float_power section (specifically in the pow() tests) of
said suite. The LTP test essentially iterates through 20000 data sets
and tests the result of pow() using this data with a pregenerated result
set in a given number of threads, during my run of the testsuite I would
receive an incorrect result error in a random iteration in a number of
the running threads.
After a bit of tracking and experimentation with pthread_mutexes around
the call to pow(), it seems the cause of the problem lies in
sysdeps/ieee754/dbl-64/e_pow.c and, more specifically, two52 - a global
variable that is set within log1() and log2(). The attached patch
corrects (at least for me) the problem I was witnessing in LTP and other
multithreaded programs using pow(). Comments?
Simon
diff -urpb glibc-2.2.4.orig/sysdeps/ieee754/dbl-64/e_pow.c glibc-2.2.4/sysdeps/ieee754/dbl-64/e_pow.c
--- glibc-2.2.4.orig/sysdeps/ieee754/dbl-64/e_pow.c Fri Oct 19 18:11:08 2001
+++ glibc-2.2.4/sysdeps/ieee754/dbl-64/e_pow.c Thu Aug 8 20:51:39 2002
@@ -189,6 +189,15 @@ static double log1(double x, double *del
double cor;
#endif
mynumber u,v;
+#ifdef BIG_ENDI
+ mynumber
+/**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */
+#else
+#ifdef LITTLE_ENDI
+ mynumber
+/**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */
+#endif
+#endif
u.x = x;
m = u.i[HIGH_HALF];
@@ -274,6 +283,15 @@ static double log2(double x, double *del
double ou1,ou2,lu1,lu2,ov,lv1,lv2,a,a1,a2;
double y,yy,z,zz,j1,j2,j3,j4,j5,j6,j7,j8;
mynumber u,v;
+#ifdef BIG_ENDI
+ mynumber
+/**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */
+#else
+#ifdef LITTLE_ENDI
+ mynumber
+/**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */
+#endif
+#endif
u.x = x;
m = u.i[HIGH_HALF];
diff -urpb glibc-2.2.4.orig/sysdeps/ieee754/dbl-64/upow.h glibc-2.2.4/sysdeps/ieee754/dbl-64/upow.h
--- glibc-2.2.4.orig/sysdeps/ieee754/dbl-64/upow.h Wed Aug 15 01:16:54 2001
+++ glibc-2.2.4/sysdeps/ieee754/dbl-64/upow.h Thu Aug 8 20:50:37 2002
@@ -42,10 +42,6 @@
/**/ bigv = {{0x4207ffff, 0xfff8016a}}, /* 1.5*2**33-1+362*2**-19 */
/**/ t52 = {{0x43300000, 0x00000000}}, /* 2**52 */
/**/ two52e = {{0x43300000, 0x000003ff}}; /* 2**52' */
-
- mynumber
-/**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */
-
#else
#ifdef LITTLE_ENDI
const static mynumber
@@ -60,10 +56,6 @@
/**/ bigv = {{0xfff8016a, 0x4207ffff}}, /* 1.5*2**33-1+362*2**-19 */
/**/ t52 = {{0x00000000, 0x43300000}}, /* 2**52 */
/**/ two52e = {{0x000003ff, 0x43300000}}; /* 2**52' */
-
- mynumber
-/**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */
-
#endif
#endif