]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 26 May 2004 04:47:00 +0000 (04:47 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 26 May 2004 04:47:00 +0000 (04:47 +0000)
2004-05-25  Steven Munroe  <sjmunroe@us.ibm.com>

* sysdeps/powerpc/fpu/Makefile: Make ld.so a dependency of libm.so.
* sysdeps/powerpc/fpu/bits/mathinline.h [__LIBC_INERNAL_MATH_INLINES]
(__ieee754_sqrt): Define as __MATH_INLINE using fsqrt instruction.
(__ieee754_sqrtf): Define as __MATH_INLINE using fsqrts instruction.
* sysdeps/powerpc/fpu/e_sqrt.c (__slow_ieee754_sqrt): Moved
implementation from w_sqrt.c.
* sysdeps/powerpc/fpu/e_sqrtf.c (__slow_ieee754_sqrtf): Moved
implementation from w_sqrtf.c.
* sysdeps/powerpc/fpu/w_sqrt.c (__sqrt): Wrapper implementation
using inline __ieee754_sqrt().
* sysdeps/powerpc/fpu/w_sqrtf.c (__sqrtf): Wrapper implementation
using inline __ieee754_sqrtf().
* sysdeps/powerpc/powerpc32/sysdep.h [__ASSEMBLER__]: Include
<sysdeps/powerpc/sysdep.h> independent of __ASSEMBLER__.
* sysdeps/powerpc/sysdep.h [__ASSEMBLER__] (PPC_FEATURE_*): Define
PPC_FEATURE_*  independent of __ASSEMBLER__.

2004-05-25  Jakub Jelinek  <jakub@redhat.com>

* sysdeps/pthread/aio_notify.c: Use <> instead of "" for aio_misc.h
include.
(aio_start_notify_thread): Define if not defined.
(notify_func_wrapper): Use it.
* sysdeps/pthread/aio_misc.c: Use <> instead of "" for aio_misc.h
include.
(aio_create_helper_thread): Define if not defined.
(__aio_create_helper_thread): New function.
(__aio_enqueue_request): Use aio_create_helper_thread.

* nis/ypclnt.c (ypall_data, ypall_foreach): Remove.
(struct ypresp_all_data): New type.
(__xdr_ypresp_all): Change second argument to
struct ypresp_all_data *.  Replace ypall_foreach and
ypall_data with objp->foreach and objp->data.
(yp_all): Remove status variable, add data.  Replace
all uses of status with data.status.  Initialize data.foreach
and data.data instead of ypall_foreach and ypall_data.

2004-05-24  Jakub Jelinek  <jakub@redhat.com>

* elf/dl-lookup.c (add_dependency): Set DF_1_NODELETE bit
in l_flags_1, not in l_flags.

14 files changed:
ChangeLog
nis/ypclnt.c
nptl/ChangeLog
nptl/sysdeps/unix/sysv/linux/aio_misc.h [new file with mode: 0644]
sysdeps/powerpc/fpu/Makefile
sysdeps/powerpc/fpu/bits/mathinline.h
sysdeps/powerpc/fpu/e_sqrt.c
sysdeps/powerpc/fpu/e_sqrtf.c
sysdeps/powerpc/fpu/w_sqrt.c
sysdeps/powerpc/fpu/w_sqrtf.c
sysdeps/powerpc/powerpc32/sysdep.h
sysdeps/powerpc/sysdep.h
sysdeps/pthread/aio_misc.c
sysdeps/pthread/aio_notify.c

index 9c1166efe844d79d2e48cca9e3f54f86f3f266fa..4d7a509a5563b566e33cd43992f3865c185f6f69 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,48 @@
+2004-05-25  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * sysdeps/powerpc/fpu/Makefile: Make ld.so a dependency of libm.so.
+       * sysdeps/powerpc/fpu/bits/mathinline.h [__LIBC_INERNAL_MATH_INLINES]
+       (__ieee754_sqrt): Define as __MATH_INLINE using fsqrt instruction.
+       (__ieee754_sqrtf): Define as __MATH_INLINE using fsqrts instruction.
+       * sysdeps/powerpc/fpu/e_sqrt.c (__slow_ieee754_sqrt): Moved
+       implementation from w_sqrt.c.
+       * sysdeps/powerpc/fpu/e_sqrtf.c (__slow_ieee754_sqrtf): Moved
+       implementation from w_sqrtf.c.
+       * sysdeps/powerpc/fpu/w_sqrt.c (__sqrt): Wrapper implementation
+       using inline __ieee754_sqrt().
+       * sysdeps/powerpc/fpu/w_sqrtf.c (__sqrtf): Wrapper implementation
+       using inline __ieee754_sqrtf().
+       * sysdeps/powerpc/powerpc32/sysdep.h [__ASSEMBLER__]: Include
+       <sysdeps/powerpc/sysdep.h> independent of __ASSEMBLER__.
+       * sysdeps/powerpc/sysdep.h [__ASSEMBLER__] (PPC_FEATURE_*): Define
+       PPC_FEATURE_*  independent of __ASSEMBLER__.
+
+2004-05-25  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/aio_notify.c: Use <> instead of "" for aio_misc.h
+       include.
+       (aio_start_notify_thread): Define if not defined.
+       (notify_func_wrapper): Use it.
+       * sysdeps/pthread/aio_misc.c: Use <> instead of "" for aio_misc.h
+       include.
+       (aio_create_helper_thread): Define if not defined.
+       (__aio_create_helper_thread): New function.
+       (__aio_enqueue_request): Use aio_create_helper_thread.
+
+       * nis/ypclnt.c (ypall_data, ypall_foreach): Remove.
+       (struct ypresp_all_data): New type.
+       (__xdr_ypresp_all): Change second argument to
+       struct ypresp_all_data *.  Replace ypall_foreach and
+       ypall_data with objp->foreach and objp->data.
+       (yp_all): Remove status variable, add data.  Replace
+       all uses of status with data.status.  Initialize data.foreach
+       and data.data instead of ypall_foreach and ypall_data.
+
+2004-05-24  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/dl-lookup.c (add_dependency): Set DF_1_NODELETE bit
+       in l_flags_1, not in l_flags.
+
 2004-04-10  Robert Millan  <robertmh@gnu.org>
 
        * sysdeps/unix/sysv/linux/bits/in.h: Cosmetic fixes to get in sync
index d6e2205fd9e72cc80d54aecf8d83f67508c1c993..ab28e6002ba674ce93a63a796a9da9c52b4e8c14 100644 (file)
@@ -618,12 +618,16 @@ yp_order (const char *indomain, const char *inmap, unsigned int *outorder)
   return YPERR_SUCCESS;
 }
 
-static void *ypall_data;
-static int (*ypall_foreach) (int status, char *key, int keylen,
-                            char *val, int vallen, char *data);
+struct ypresp_all_data
+{
+  unsigned long status;
+  void *data;
+  int (*foreach) (int status, char *key, int keylen,
+                 char *val, int vallen, char *data);
+};
 
 static bool_t
-__xdr_ypresp_all (XDR *xdrs, u_long *objp)
+__xdr_ypresp_all (XDR *xdrs, struct ypresp_all_data *objp)
 {
   while (1)
     {
@@ -633,13 +637,13 @@ __xdr_ypresp_all (XDR *xdrs, u_long *objp)
       if (!xdr_ypresp_all (xdrs, &resp))
        {
          xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
-         *objp = YP_YPERR;
+         objp->status = YP_YPERR;
          return FALSE;
        }
       if (resp.more == 0)
        {
          xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
-         *objp = YP_NOMORE;
+         objp->status = YP_NOMORE;
          return TRUE;
        }
 
@@ -656,24 +660,24 @@ __xdr_ypresp_all (XDR *xdrs, u_long *objp)
               But we are allowed to add data behind the buffer,
               if we don't modify the length. So add an extra NUL
               character to avoid trouble with broken code. */
-           *objp = YP_TRUE;
+           objp->status = YP_TRUE;
            memcpy (key, resp.ypresp_all_u.val.key.keydat_val, keylen);
            key[keylen] = '\0';
            memcpy (val, resp.ypresp_all_u.val.val.valdat_val, vallen);
            val[vallen] = '\0';
            xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
-           if ((*ypall_foreach) (*objp, key, keylen,
-                                 val, vallen, ypall_data))
+           if ((*objp->foreach) (objp->status, key, keylen,
+                                 val, vallen, objp->data))
              return TRUE;
          }
          break;
        default:
-         *objp = resp.ypresp_all_u.val.stat;
+         objp->status = resp.ypresp_all_u.val.stat;
          xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
          /* Sun says we don't need to make this call, but must return
             immediatly. Since Solaris makes this call, we will call
             the callback function, too. */
-         (*ypall_foreach) (*objp, NULL, 0, NULL, 0, ypall_data);
+         (*objp->foreach) (objp->status, NULL, 0, NULL, 0, objp->data);
          return TRUE;
        }
     }
@@ -689,7 +693,7 @@ yp_all (const char *indomain, const char *inmap,
   enum clnt_stat result;
   struct sockaddr_in clnt_sin;
   CLIENT *clnt;
-  unsigned long status;
+  struct ypresp_all_data data;
   int clnt_sock;
   int saved_errno = errno;
 
@@ -725,12 +729,12 @@ yp_all (const char *indomain, const char *inmap,
       req.domain = (char *) indomain;
       req.map = (char *) inmap;
 
-      ypall_foreach = incallback->foreach;
-      ypall_data = (void *) incallback->data;
+      data.foreach = incallback->foreach;
+      data.data = (void *) incallback->data;
 
       result = clnt_call (clnt, YPPROC_ALL, (xdrproc_t) xdr_ypreq_nokey,
                          (caddr_t) &req, (xdrproc_t) __xdr_ypresp_all,
-                         (caddr_t) &status, RPCTIMEOUT);
+                         (caddr_t) &data, RPCTIMEOUT);
 
       if (result != RPC_SUCCESS)
        {
@@ -744,10 +748,10 @@ yp_all (const char *indomain, const char *inmap,
 
       clnt_destroy (clnt);
 
-      if (res == YPERR_SUCCESS && status != YP_NOMORE)
+      if (res == YPERR_SUCCESS && data.status != YP_NOMORE)
        {
          __set_errno (saved_errno);
-         return ypprot_err (status);
+         return ypprot_err (data.status);
        }
       ++try;
     }
index 5f1f61c088feb7ddb01332263ae0a11e99064be7..9164affc9d8ce75c7f4d405d8cca6aea6db00564 100644 (file)
@@ -1,3 +1,7 @@
+2004-05-25  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/aio_misc.h: New file.
+
 2004-05-21  Jakub Jelinek  <jakub@redhat.com>
 
        * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Compare
diff --git a/nptl/sysdeps/unix/sysv/linux/aio_misc.h b/nptl/sysdeps/unix/sysv/linux/aio_misc.h
new file mode 100644 (file)
index 0000000..7b0bac7
--- /dev/null
@@ -0,0 +1,67 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _AIO_MISC_H
+# include_next <aio_misc.h>
+# include <signal.h>
+# include <sysdep.h>
+# include <pthread.h>
+
+# define aio_start_notify_thread __aio_start_notify_thread
+# define aio_create_helper_thread __aio_create_helper_thread
+
+extern inline void
+__aio_start_notify_thread (void)
+{
+  sigset_t ss;
+  sigemptyset (&ss);
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, NULL, _NSIG / 8);
+}
+
+extern inline int
+__aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), void *arg)
+{
+  pthread_attr_t attr;
+
+  /* Make sure the thread is created detached.  */
+  pthread_attr_init (&attr);
+  pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+  /* The helper thread needs only very little resources.  */
+  (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+  /* Block all signals in the helper thread.  To do this thoroughly we
+     temporarily have to block all signals here.  */
+  sigset_t ss;
+  sigset_t oss;
+  sigfillset (&ss);
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, &oss, _NSIG / 8);
+
+  int ret = pthread_create (threadp, &attr, tf, arg);
+
+  /* Restore the signal mask.  */
+  INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &oss, NULL,
+                   _NSIG / 8);
+
+  (void) pthread_attr_destroy (&attr);
+  return ret;
+}                                                                                 
+#endif
index bf2ed92e7b05a36f5f5ff23b1de88deb32b06454..d0fe4a8ba12bbcc0cade9e6959327b9e4884d8ac 100644 (file)
@@ -1,3 +1,6 @@
 ifeq ($(subdir),math)
 libm-support += fenv_const fe_nomask t_sqrt
+
+# libm needs ld.so to access dl_hwcap
+$(objpfx)libm.so: $(elfobjdir)/ld.so
 endif
index e692df9b1a828f96007ec94c0795241ba1ef0990..d9206d4facb34497e8f7ccec52391f72ac1cd415 100644 (file)
@@ -121,4 +121,56 @@ fdimf (float __x, float __y) __THROW
 
 #endif /* __USE_ISOC99 */
 #endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
+
+/* This code is used internally in the GNU libc.  */
+#  ifdef __LIBC_INTERNAL_MATH_INLINES
+
+#include <sysdep.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+extern double __slow_ieee754_sqrt (double);
+__MATH_INLINE double
+__ieee754_sqrt (double __x)
+{
+  double __z;
+  
+  /* If the CPU is 64-bit we can use the optional FP instructions we.  */
+  if ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
+  {
+    /* Volatile is required to prevent the compiler from moving the 
+       fsqrt instruction above the branch.  */
+     __asm __volatile (
+       "       fsqrt   %0,%1\n"
+               : "=f" (__z)
+               : "f" (__x));
+  }
+  else
+     __z = __slow_ieee754_sqrt(__x);
+     
+  return __z;
+}
+
+extern float __slow_ieee754_sqrtf (float);
+__MATH_INLINE float
+__ieee754_sqrtf (float __x)
+{
+  float __z;
+  
+  /* If the CPU is 64-bit we can use the optional FP instructions we.  */
+  if ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
+  {
+    /* Volatile is required to prevent the compiler from moving the 
+       fsqrts instruction above the branch.  */
+     __asm __volatile (
+       "       fsqrts  %0,%1\n"
+               : "=f" (__z)
+               : "f" (__x));
+  }
+  else
+     __z = __slow_ieee754_sqrtf(__x);
+     
+  return __z;
+}
+#  endif /* __LIBC_INTERNAL_MATH_INLINES */
 #endif /* __GNUC__ && !_SOFT_FLOAT */
index 9416ea60c81d45b03d857c1cdd6f614b6173af7e..eb9984d0a1f54146e142b3855fedf6d0348ac2ce 100644 (file)
@@ -1 +1,185 @@
-/* __ieee754_sqrt is in w_sqrt.c  */
+/* Double-precision floating point square root.
+   Copyright (C) 1997, 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <fenv_libc.h>
+#include <inttypes.h>
+
+#include <sysdep.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+static const double almost_half = 0.5000000000000001;  /* 0.5 + 2^-53 */
+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
+static const float two108 = 3.245185536584267269e+32;
+static const float twom54 = 5.551115123125782702e-17;
+extern const float __t_sqrt[1024];
+
+/* The method is based on a description in
+   Computation of elementary functions on the IBM RISC System/6000 processor,
+   P. W. Markstein, IBM J. Res. Develop, 34(1) 1990.
+   Basically, it consists of two interleaved Newton-Rhapson approximations,
+   one to find the actual square root, and one to find its reciprocal
+   without the expense of a division operation.   The tricky bit here
+   is the use of the POWER/PowerPC multiply-add operation to get the
+   required accuracy with high speed.
+
+   The argument reduction works by a combination of table lookup to
+   obtain the initial guesses, and some careful modification of the
+   generated guesses (which mostly runs on the integer unit, while the
+   Newton-Rhapson is running on the FPU).  */
+
+#ifdef __STDC__
+double
+__slow_ieee754_sqrt (double x)
+#else
+double
+__slow_ieee754_sqrt (x)
+     double x;
+#endif
+{
+  const float inf = a_inf.value;
+
+  if (x > 0)
+    {
+      /* schedule the EXTRACT_WORDS to get separation between the store
+         and the load.  */
+      ieee_double_shape_type ew_u;
+      ieee_double_shape_type iw_u;
+      ew_u.value = (x);
+      if (x != inf)
+       {
+         /* Variables named starting with 's' exist in the
+            argument-reduced space, so that 2 > sx >= 0.5,
+            1.41... > sg >= 0.70.., 0.70.. >= sy > 0.35... .
+            Variables named ending with 'i' are integer versions of
+            floating-point values.  */
+         double sx;    /* The value of which we're trying to find the
+                          square root.  */
+         double sg, g; /* Guess of the square root of x.  */
+         double sd, d; /* Difference between the square of the guess and x.  */
+         double sy;    /* Estimate of 1/2g (overestimated by 1ulp).  */
+         double sy2;   /* 2*sy */
+         double e;     /* Difference between y*g and 1/2 (se = e * fsy).  */
+         double shx;   /* == sx * fsg */
+         double fsg;   /* sg*fsg == g.  */
+         fenv_t fe;    /* Saved floating-point environment (stores rounding
+                          mode and whether the inexact exception is
+                          enabled).  */
+         uint32_t xi0, xi1, sxi, fsgi;
+         const float *t_sqrt;
+
+         fe = fegetenv_register ();
+         /* complete the EXTRACT_WORDS (xi0,xi1,x) operation.  */
+         xi0 = ew_u.parts.msw;
+         xi1 = ew_u.parts.lsw;
+         relax_fenv_state ();
+         sxi = (xi0 & 0x3fffffff) | 0x3fe00000;
+         /* schedule the INSERT_WORDS (sx, sxi, xi1) to get separation
+            between the store and the load.  */
+         iw_u.parts.msw = sxi;
+         iw_u.parts.lsw = xi1;
+         t_sqrt = __t_sqrt + (xi0 >> (52 - 32 - 8 - 1) & 0x3fe);
+         sg = t_sqrt[0];
+         sy = t_sqrt[1];
+         /* complete the INSERT_WORDS (sx, sxi, xi1) operation.  */
+         sx = iw_u.value;
+
+         /* Here we have three Newton-Rhapson iterations each of a
+            division and a square root and the remainder of the
+            argument reduction, all interleaved.   */
+         sd = -(sg * sg - sx);
+         fsgi = (xi0 + 0x40000000) >> 1 & 0x7ff00000;
+         sy2 = sy + sy;
+         sg = sy * sd + sg;    /* 16-bit approximation to sqrt(sx). */
+
+         /* schedule the INSERT_WORDS (fsg, fsgi, 0) to get separation
+            between the store and the load.  */
+         INSERT_WORDS (fsg, fsgi, 0);
+         iw_u.parts.msw = fsgi;
+         iw_u.parts.lsw = (0);
+         e = -(sy * sg - almost_half);
+         sd = -(sg * sg - sx);
+         if ((xi0 & 0x7ff00000) == 0)
+           goto denorm;
+         sy = sy + e * sy2;
+         sg = sg + sy * sd;    /* 32-bit approximation to sqrt(sx).  */
+         sy2 = sy + sy;
+         /* complete the INSERT_WORDS (fsg, fsgi, 0) operation.  */
+         fsg = iw_u.value;
+         e = -(sy * sg - almost_half);
+         sd = -(sg * sg - sx);
+         sy = sy + e * sy2;
+         shx = sx * fsg;
+         sg = sg + sy * sd;    /* 64-bit approximation to sqrt(sx),
+                                  but perhaps rounded incorrectly.  */
+         sy2 = sy + sy;
+         g = sg * fsg;
+         e = -(sy * sg - almost_half);
+         d = -(g * sg - shx);
+         sy = sy + e * sy2;
+         fesetenv_register (fe);
+         return g + sy * d;
+       denorm:
+         /* For denormalised numbers, we normalise, calculate the
+            square root, and return an adjusted result.  */
+         fesetenv_register (fe);
+         return __slow_ieee754_sqrt (x * two108) * twom54;
+       }
+    }
+  else if (x < 0)
+    {
+      /* For some reason, some PowerPC32 processors don't implement
+         FE_INVALID_SQRT.  */
+#ifdef FE_INVALID_SQRT
+      feraiseexcept (FE_INVALID_SQRT);
+      if (!fetestexcept (FE_INVALID))
+#endif
+       feraiseexcept (FE_INVALID);
+      x = a_nan.value;
+    }
+  return f_wash (x);
+}
+
+#ifdef __STDC__
+double
+__ieee754_sqrt (double x)
+#else
+double
+__ieee754_sqrt (x)
+     double x;
+#endif
+{
+  double z;
+
+  /* If the CPU is 64-bit we can use the optional FP instructions we.  */
+  if ((GLRO (dl_hwcap) & PPC_FEATURE_64) != 0)
+    {
+      /* Volatile is required to prevent the compiler from moving the 
+         fsqrt instruction above the branch.  */
+      __asm __volatile ("      fsqrt   %0,%1\n"
+                               :"=f" (z):"f" (x));
+    }
+  else
+    z = __slow_ieee754_sqrt (x);
+
+  return z;
+}
index 01c76d67571c0ba64d64bdce3ce86e129b030ff3..9b701012afe59c20be3a548cd51d2b274e7357f8 100644 (file)
@@ -1 +1,162 @@
-/* __ieee754_sqrtf is in w_sqrtf.c  */
+/* Single-precision floating point square root.
+   Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <fenv_libc.h>
+#include <inttypes.h>
+
+#include <sysdep.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+static const float almost_half = 0.50000006;   /* 0.5 + 2^-24 */
+static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
+static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
+static const float two48 = 281474976710656.0;
+static const float twom24 = 5.9604644775390625e-8;
+extern const float __t_sqrt[1024];
+
+/* The method is based on a description in
+   Computation of elementary functions on the IBM RISC System/6000 processor,
+   P. W. Markstein, IBM J. Res. Develop, 34(1) 1990.
+   Basically, it consists of two interleaved Newton-Rhapson approximations,
+   one to find the actual square root, and one to find its reciprocal
+   without the expense of a division operation.   The tricky bit here
+   is the use of the POWER/PowerPC multiply-add operation to get the
+   required accuracy with high speed.
+
+   The argument reduction works by a combination of table lookup to
+   obtain the initial guesses, and some careful modification of the
+   generated guesses (which mostly runs on the integer unit, while the
+   Newton-Rhapson is running on the FPU).  */
+
+#ifdef __STDC__
+float
+__slow_ieee754_sqrtf (float x)
+#else
+float
+__slow_ieee754_sqrtf (x)
+     float x;
+#endif
+{
+  const float inf = a_inf.value;
+
+  if (x > 0)
+    {
+      if (x != inf)
+       {
+         /* Variables named starting with 's' exist in the
+            argument-reduced space, so that 2 > sx >= 0.5,
+            1.41... > sg >= 0.70.., 0.70.. >= sy > 0.35... .
+            Variables named ending with 'i' are integer versions of
+            floating-point values.  */
+         float sx;             /* The value of which we're trying to find the square
+                                  root.  */
+         float sg, g;          /* Guess of the square root of x.  */
+         float sd, d;          /* Difference between the square of the guess and x.  */
+         float sy;             /* Estimate of 1/2g (overestimated by 1ulp).  */
+         float sy2;            /* 2*sy */
+         float e;              /* Difference between y*g and 1/2 (note that e==se).  */
+         float shx;            /* == sx * fsg */
+         float fsg;            /* sg*fsg == g.  */
+         fenv_t fe;            /* Saved floating-point environment (stores rounding
+                                  mode and whether the inexact exception is
+                                  enabled).  */
+         uint32_t xi, sxi, fsgi;
+         const float *t_sqrt;
+
+         GET_FLOAT_WORD (xi, x);
+         fe = fegetenv_register ();
+         relax_fenv_state ();
+         sxi = (xi & 0x3fffffff) | 0x3f000000;
+         SET_FLOAT_WORD (sx, sxi);
+         t_sqrt = __t_sqrt + (xi >> (23 - 8 - 1) & 0x3fe);
+         sg = t_sqrt[0];
+         sy = t_sqrt[1];
+
+         /* Here we have three Newton-Rhapson iterations each of a
+            division and a square root and the remainder of the
+            argument reduction, all interleaved.   */
+         sd = -(sg * sg - sx);
+         fsgi = (xi + 0x40000000) >> 1 & 0x7f800000;
+         sy2 = sy + sy;
+         sg = sy * sd + sg;    /* 16-bit approximation to sqrt(sx). */
+         e = -(sy * sg - almost_half);
+         SET_FLOAT_WORD (fsg, fsgi);
+         sd = -(sg * sg - sx);
+         sy = sy + e * sy2;
+         if ((xi & 0x7f800000) == 0)
+           goto denorm;
+         shx = sx * fsg;
+         sg = sg + sy * sd;    /* 32-bit approximation to sqrt(sx),
+                                  but perhaps rounded incorrectly.  */
+         sy2 = sy + sy;
+         g = sg * fsg;
+         e = -(sy * sg - almost_half);
+         d = -(g * sg - shx);
+         sy = sy + e * sy2;
+         fesetenv_register (fe);
+         return g + sy * d;
+       denorm:
+         /* For denormalised numbers, we normalise, calculate the
+            square root, and return an adjusted result.  */
+         fesetenv_register (fe);
+         return __slow_ieee754_sqrtf (x * two48) * twom24;
+       }
+    }
+  else if (x < 0)
+    {
+      /* For some reason, some PowerPC32 processors don't implement
+         FE_INVALID_SQRT.  */
+#ifdef FE_INVALID_SQRT
+      feraiseexcept (FE_INVALID_SQRT);
+      if (!fetestexcept (FE_INVALID))
+#endif
+       feraiseexcept (FE_INVALID);
+      x = a_nan.value;
+    }
+  return f_washf (x);
+}
+
+
+#ifdef __STDC__
+float
+__ieee754_sqrtf (float x)
+#else
+float
+__ieee754_sqrtf (x)
+     float x;
+#endif
+{
+  double z;
+
+  /* If the CPU is 64-bit we can use the optional FP instructions we.  */
+  if ((GLRO (dl_hwcap) & PPC_FEATURE_64) != 0)
+    {
+      /* Volatile is required to prevent the compiler from moving the 
+         fsqrt instruction above the branch.  */
+      __asm __volatile ("      fsqrts  %0,%1\n"
+                               :"=f" (z):"f" (x));
+    }
+  else
+    z = __slow_ieee754_sqrtf (x);
+
+  return z;
+}
index ff0331725c18ac2f06dbd5d57fe573d2677f63ff..806d8e4907dcf02bed8541230acabceb55003849 100644 (file)
@@ -1,5 +1,5 @@
-/* Double-precision floating point square root.
-   Copyright (C) 1997, 2002, 2003 Free Software Foundation, Inc.
+/* Double-precision floating point square root wrapper.
+   Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <math.h>
-#include <math_private.h>
+#include "math.h"
+#include "math_private.h"
 #include <fenv_libc.h>
-#include <inttypes.h>
 
-static const double almost_half = 0.5000000000000001;  /* 0.5 + 2^-53 */
-static const ieee_float_shape_type a_nan = { .word = 0x7fc00000 };
-static const ieee_float_shape_type a_inf = { .word = 0x7f800000 };
-static const float two108 = 3.245185536584267269e+32;
-static const float twom54 = 5.551115123125782702e-17;
-extern const float __t_sqrt[1024];
-
-/* The method is based on a description in
-   Computation of elementary functions on the IBM RISC System/6000 processor,
-   P. W. Markstein, IBM J. Res. Develop, 34(1) 1990.
-   Basically, it consists of two interleaved Newton-Rhapson approximations,
-   one to find the actual square root, and one to find its reciprocal
-   without the expense of a division operation.   The tricky bit here
-   is the use of the POWER/PowerPC multiply-add operation to get the
-   required accuracy with high speed.
-
-   The argument reduction works by a combination of table lookup to
-   obtain the initial guesses, and some careful modification of the
-   generated guesses (which mostly runs on the integer unit, while the
-   Newton-Rhapson is running on the FPU).  */
+#ifdef __STDC__
 double
-__sqrt(double x)
-{
-  const float inf = a_inf.value;
-  /* x = f_wash(x); *//* This ensures only one exception for SNaN. */
-  if (x > 0)
-    {
-      if (x != inf)
-       {
-         /* Variables named starting with 's' exist in the
-            argument-reduced space, so that 2 > sx >= 0.5,
-            1.41... > sg >= 0.70.., 0.70.. >= sy > 0.35... .
-            Variables named ending with 'i' are integer versions of
-            floating-point values.  */
-         double sx;   /* The value of which we're trying to find the
-                         square root.  */
-         double sg,g; /* Guess of the square root of x.  */
-         double sd,d; /* Difference between the square of the guess and x.  */
-         double sy;   /* Estimate of 1/2g (overestimated by 1ulp).  */
-         double sy2;  /* 2*sy */
-         double e;    /* Difference between y*g and 1/2 (se = e * fsy).  */
-         double shx;  /* == sx * fsg */
-         double fsg;  /* sg*fsg == g.  */
-         fenv_t fe;  /* Saved floating-point environment (stores rounding
-                        mode and whether the inexact exception is
-                        enabled).  */
-         uint32_t xi0, xi1, sxi, fsgi;
-         const float *t_sqrt;
-
-         fe = fegetenv_register();
-         EXTRACT_WORDS (xi0,xi1,x);
-         relax_fenv_state();
-         sxi = (xi0 & 0x3fffffff) | 0x3fe00000;
-         INSERT_WORDS (sx, sxi, xi1);
-         t_sqrt = __t_sqrt + (xi0 >> (52-32-8-1)  & 0x3fe);
-         sg = t_sqrt[0];
-         sy = t_sqrt[1];
-
-         /* Here we have three Newton-Rhapson iterations each of a
-            division and a square root and the remainder of the
-            argument reduction, all interleaved.   */
-         sd  = -(sg*sg - sx);
-         fsgi = (xi0 + 0x40000000) >> 1 & 0x7ff00000;
-         sy2 = sy + sy;
-         sg  = sy*sd + sg;  /* 16-bit approximation to sqrt(sx). */
-         INSERT_WORDS (fsg, fsgi, 0);
-         e   = -(sy*sg - almost_half);
-         sd  = -(sg*sg - sx);
-         if ((xi0 & 0x7ff00000) == 0)
-           goto denorm;
-         sy  = sy + e*sy2;
-         sg  = sg + sy*sd;  /* 32-bit approximation to sqrt(sx).  */
-         sy2 = sy + sy;
-         e   = -(sy*sg - almost_half);
-         sd  = -(sg*sg - sx);
-         sy  = sy + e*sy2;
-         shx = sx * fsg;
-         sg  = sg + sy*sd;  /* 64-bit approximation to sqrt(sx),
-                               but perhaps rounded incorrectly.  */
-         sy2 = sy + sy;
-         g   = sg * fsg;
-         e   = -(sy*sg - almost_half);
-         d   = -(g*sg - shx);
-         sy  = sy + e*sy2;
-         fesetenv_register (fe);
-         return g + sy*d;
-       denorm:
-         /* For denormalised numbers, we normalise, calculate the
-            square root, and return an adjusted result.  */
-         fesetenv_register (fe);
-         return __sqrt(x * two108) * twom54;
-       }
-    }
-  else if (x < 0)
-    {
-#ifdef FE_INVALID_SQRT
-      feraiseexcept (FE_INVALID_SQRT);
-      /* For some reason, some PowerPC processors don't implement
-        FE_INVALID_SQRT.  I guess no-one ever thought they'd be
-        used for square roots... :-) */
-      if (!fetestexcept (FE_INVALID))
+__sqrt (double x)              /* wrapper sqrt */
+#else
+double
+__sqrt (x)                     /* wrapper sqrt */
+     double x;
 #endif
-       feraiseexcept (FE_INVALID);
-#ifndef _IEEE_LIBM
-      if (_LIB_VERSION != _IEEE_)
-       x = __kernel_standard(x,x,26);
-      else
+{
+#ifdef _IEEE_LIBM
+  return __ieee754_sqrt (x);
+#else
+  double z;
+  z = __ieee754_sqrt (x);
+  if (_LIB_VERSION == _IEEE_ || (x != x))
+    return z;
+
+  if (x < 0.0)
+    return __kernel_standard (x, x, 26);       /* sqrt(negative) */
+  else
+    return z;
 #endif
-      x = a_nan.value;
-    }
-  return f_wash(x);
 }
 
 weak_alias (__sqrt, sqrt)
-/* Strictly, this is wrong, but the only places where _ieee754_sqrt is
-   used will not pass in a negative result.  */
-strong_alias(__sqrt,__ieee754_sqrt)
-
 #ifdef NO_LONG_DOUBLE
-weak_alias (__sqrt, __sqrtl)
-weak_alias (__sqrt, sqrtl)
+  strong_alias (__sqrt, __sqrtl) weak_alias (__sqrt, sqrtl)
 #endif
index 8eb94d8e3bc3f9b661f6fe9e41332730858a68cf..e3f3c995e80ee7fc5134b95a4b260f78bf863f85 100644 (file)
@@ -1,5 +1,5 @@
-/* Single-precision floating point square root.
-   Copyright (C) 1997, 2003 Free Software Foundation, Inc.
+/* Single-precision floating point square root wrapper.
+   Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <math.h>
-#include <math_private.h>
+#include "math.h"
+#include "math_private.h"
 #include <fenv_libc.h>
-#include <inttypes.h>
 
-static const float almost_half = 0.50000006;  /* 0.5 + 2^-24 */
-static const ieee_float_shape_type a_nan = { .word = 0x7fc00000 };
-static const ieee_float_shape_type a_inf = { .word = 0x7f800000 };
-static const float two48 = 281474976710656.0;
-static const float twom24 = 5.9604644775390625e-8;
-extern const float __t_sqrt[1024];
+#include <sysdep.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
 
-/* The method is based on a description in
-   Computation of elementary functions on the IBM RISC System/6000 processor,
-   P. W. Markstein, IBM J. Res. Develop, 34(1) 1990.
-   Basically, it consists of two interleaved Newton-Rhapson approximations,
-   one to find the actual square root, and one to find its reciprocal
-   without the expense of a division operation.   The tricky bit here
-   is the use of the POWER/PowerPC multiply-add operation to get the
-   required accuracy with high speed.
-
-   The argument reduction works by a combination of table lookup to
-   obtain the initial guesses, and some careful modification of the
-   generated guesses (which mostly runs on the integer unit, while the
-   Newton-Rhapson is running on the FPU).  */
+#ifdef __STDC__
 float
-__sqrtf(float x)
-{
-  const float inf = a_inf.value;
-  /* x = f_washf(x); *//* This ensures only one exception for SNaN. */
-  if (x > 0)
-    {
-      if (x != inf)
-       {
-         /* Variables named starting with 's' exist in the
-            argument-reduced space, so that 2 > sx >= 0.5,
-            1.41... > sg >= 0.70.., 0.70.. >= sy > 0.35... .
-            Variables named ending with 'i' are integer versions of
-            floating-point values.  */
-         float sx;   /* The value of which we're trying to find the square
-                        root.  */
-         float sg,g; /* Guess of the square root of x.  */
-         float sd,d; /* Difference between the square of the guess and x.  */
-         float sy;   /* Estimate of 1/2g (overestimated by 1ulp).  */
-         float sy2;  /* 2*sy */
-         float e;    /* Difference between y*g and 1/2 (note that e==se).  */
-         float shx;  /* == sx * fsg */
-         float fsg;  /* sg*fsg == g.  */
-         fenv_t fe;  /* Saved floating-point environment (stores rounding
-                        mode and whether the inexact exception is
-                        enabled).  */
-         uint32_t xi, sxi, fsgi;
-         const float *t_sqrt;
-
-         GET_FLOAT_WORD (xi, x);
-         fe = fegetenv_register ();
-         relax_fenv_state ();
-         sxi = (xi & 0x3fffffff) | 0x3f000000;
-         SET_FLOAT_WORD (sx, sxi);
-         t_sqrt = __t_sqrt + (xi >> (23-8-1)  & 0x3fe);
-         sg = t_sqrt[0];
-         sy = t_sqrt[1];
-         
-         /* Here we have three Newton-Rhapson iterations each of a
-            division and a square root and the remainder of the
-            argument reduction, all interleaved.   */
-         sd  = -(sg*sg - sx);
-         fsgi = (xi + 0x40000000) >> 1 & 0x7f800000;
-         sy2 = sy + sy;
-         sg  = sy*sd + sg;  /* 16-bit approximation to sqrt(sx). */
-         e   = -(sy*sg - almost_half);
-         SET_FLOAT_WORD (fsg, fsgi);
-         sd  = -(sg*sg - sx);
-         sy  = sy + e*sy2;
-         if ((xi & 0x7f800000) == 0)
-           goto denorm;
-         shx = sx * fsg;
-         sg  = sg + sy*sd;  /* 32-bit approximation to sqrt(sx),
-                               but perhaps rounded incorrectly.  */
-         sy2 = sy + sy;
-         g   = sg * fsg;
-         e   = -(sy*sg - almost_half);
-         d   = -(g*sg - shx);
-         sy  = sy + e*sy2;
-         fesetenv_register (fe);
-         return g + sy*d;
-       denorm:
-         /* For denormalised numbers, we normalise, calculate the
-            square root, and return an adjusted result.  */
-         fesetenv_register (fe);
-         return __sqrtf(x * two48) * twom24;
-       }
-    }
-  else if (x < 0)
-    {
-#ifdef FE_INVALID_SQRT
-      feraiseexcept (FE_INVALID_SQRT);
-      /* For some reason, some PowerPC processors don't implement
-        FE_INVALID_SQRT.  I guess no-one ever thought they'd be
-        used for square roots... :-) */
-      if (!fetestexcept (FE_INVALID))
+__sqrtf (float x)              /* wrapper sqrtf */
+#else
+float
+__sqrtf (x)                    /* wrapper sqrtf */
+     float x;
 #endif
-       feraiseexcept (FE_INVALID);
-#ifndef _IEEE_LIBM
-      if (_LIB_VERSION != _IEEE_)
-       x = __kernel_standard(x,x,126);
-      else
+{
+#ifdef _IEEE_LIBM
+  return __ieee754_sqrtf (x);
+#else
+  float z;
+  z = __ieee754_sqrtf (x);
+
+  if (_LIB_VERSION == _IEEE_ || (x != x))
+    return z;
+
+  if (x < (float) 0.0)
+    /* sqrtf(negative) */
+    return (float) __kernel_standard ((double) x, (double) x, 126);
+  else
+    return z;
 #endif
-      x = a_nan.value;
-    }
-  return f_washf(x);
 }
 
 weak_alias (__sqrtf, sqrtf)
-/* Strictly, this is wrong, but the only places where _ieee754_sqrt is
-   used will not pass in a negative result.  */
-strong_alias(__sqrtf,__ieee754_sqrtf)
index 43179d14f05d538caba8616b6b1bb239ca1f1337..59761f75b9812ea89dbe88df38b62a6135e0690d 100644 (file)
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#ifdef __ASSEMBLER__
-
 #include <sysdeps/powerpc/sysdep.h>
 
+#ifdef __ASSEMBLER__
+
 #ifdef __ELF__
 
 /* If compiled for profiling, call `_mcount' at the start of each
index 214ac6a2ed1a90d4b03d257833afbf284e008592..fb668ad51f1e23ab70f5222bed2208ec4ddff156 100644 (file)
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+/* 
+ * Powerpc Feature masks for the Aux Vector Hardware Capabilities (AT_HWCAP). 
+ * This entry is copied to _dl_hwcap or rtld_global._dl_hwcap during startup.
+ * The following must match the kernels linux/asm/cputable.h.  
+ */
+#define PPC_FEATURE_32                 0x80000000 /* 32-bit mode. */
+#define PPC_FEATURE_64                 0x40000000 /* 64-bit mode. */
+#define PPC_FEATURE_601_INSTR          0x20000000 /* 601 chip, Old POWER ISA.  */
+#define PPC_FEATURE_HAS_ALTIVEC                0x10000000 /* SIMD/Vector Unit.  */
+#define PPC_FEATURE_HAS_FPU            0x08000000 /* Floating Point Unit.  */
+#define PPC_FEATURE_HAS_MMU            0x04000000 /* Memory Management Unit.  */
+#define PPC_FEATURE_HAS_4xxMAC         0x02000000 /* 4xx Multiply Accumulator.  */
+#define PPC_FEATURE_UNIFIED_CACHE      0x01000000 /* Unified I/D cache.  */
+
 #ifdef __ASSEMBLER__
 
 /* Symbolic names for the registers.  The only portable way to write asm
 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
 
 #endif /* __ELF__ */
-
-/* 
- * Powerpc Feature masks for the Aux Vector Hardware Capabilities (AT_HWCAP). 
- * This entry is copied to _dl_hwcap or rtld_global._dl_hwcap during startup.
- * The following must match the kernels linux/asm/cputable.h.  
- */
-#define PPC_FEATURE_32                 0x80000000 /* 32-bit mode. */
-#define PPC_FEATURE_64                 0x40000000 /* 64-bit mode. */
-#define PPC_FEATURE_601_INSTR          0x20000000 /* 601 chip, Old POWER ISA.  */
-#define PPC_FEATURE_HAS_ALTIVEC                0x10000000 /* SIMD/Vector Unit.  */
-#define PPC_FEATURE_HAS_FPU            0x08000000 /* Floating Point Unit.  */
-#define PPC_FEATURE_HAS_MMU            0x04000000 /* Memory Management Unit.  */
-#define PPC_FEATURE_HAS_4xxMAC         0x02000000 /* 4xx Multiply Accumulator.  */
-#define PPC_FEATURE_UNIFIED_CACHE      0x01000000 /* Unified I/D cache.  */
-
 #endif /* __ASSEMBLER__ */
+
index c2eb674212c5ffd0d45e42640133bdc223e9f53e..1da3ad2c73985a29f932c91d7016c60d485afad6 100644 (file)
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/time.h>
+#include <aio_misc.h>
 
-#include "aio_misc.h"
+#ifndef aio_create_helper_thread
+# define aio_create_helper_thread __aio_create_helper_thread
+
+extern inline int
+__aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), void *arg)
+{
+  pthread_attr_t attr;
+
+  /* Make sure the thread is created detached.  */
+  pthread_attr_init (&attr);
+  pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+  int ret = pthread_create (threadp, &attr, tf, arg);
+
+  (void) pthread_attr_destroy (&attr);
+  return ret;
+}                                                                                 
+
+#endif
 
 static void add_request_to_runlist (struct requestlist *newrequest);
 
@@ -400,16 +419,11 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
       if (nthreads < optim.aio_threads && idle_thread_count == 0)
        {
          pthread_t thid;
-         pthread_attr_t attr;
-
-         /* Make sure the thread is created detached.  */
-         pthread_attr_init (&attr);
-         pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
 
          running = newp->running = allocated;
 
          /* Now try to start a thread.  */
-         if (pthread_create (&thid, &attr, handle_fildes_io, newp) == 0)
+         if (aio_create_helper_thread (&thid, handle_fildes_io, newp) == 0)
            /* We managed to enqueue the request.  All errors which can
               happen now can be recognized by calls to `aio_return' and
               `aio_error'.  */
index d1c0a63fbffe1dc43f875849e6aea16b8d70d47e..877e8d936331c138c0ae3459cb8587dcb7ee808c 100644 (file)
@@ -1,5 +1,6 @@
 /* Notify initiator of AIO request.
-   Copyright (C) 1997,98,99,2000,2001,2003 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
 #include <pthread.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "aio_misc.h"
+#include <aio_misc.h>
 
+#ifndef aio_start_notify_thread
+# define aio_start_notify_thread() do { } while (0)
+#endif
 
 struct notify_func
   {
@@ -34,6 +38,7 @@ struct notify_func
 static void *
 notify_func_wrapper (void *arg)
 {
+  aio_start_notify_thread ();
   struct notify_func *const n = arg;
   void (*func) (sigval_t) = n->func;
   sigval_t value = n->value;