summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2006-03-28 09:36:28 +0000
committerJakub Jelinek <jakub@redhat.com>2006-03-28 09:36:28 +0000
commit5a6a773f6c388e7740afb495fcd03d3b500f30cb (patch)
treead7b4e3dd8bb8a750bf6b3a016c591e5d98026dc
parent0c20be13c576b849ab201bd887a6585973a49d0e (diff)
Updated to fedora-glibc-20060328T0900cvs/fedora-
-rw-r--r--ChangeLog172
-rw-r--r--elf/Makefile17
-rw-r--r--elf/dl-load.c25
-rw-r--r--elf/rtld.c40
-rw-r--r--elf/tst-audit2.c50
-rw-r--r--elf/tst-leaks1.c25
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in8
-rwxr-xr-xmath/gen-libm-test.pl11
-rw-r--r--math/libm-test.inc1079
-rw-r--r--nis/nss_nisplus/nisplus-alias.c5
-rw-r--r--nis/nss_nisplus/nisplus-ethers.c4
-rw-r--r--nis/nss_nisplus/nisplus-grp.c5
-rw-r--r--nis/nss_nisplus/nisplus-hosts.c4
-rw-r--r--nis/nss_nisplus/nisplus-network.c4
-rw-r--r--nis/nss_nisplus/nisplus-proto.c5
-rw-r--r--nis/nss_nisplus/nisplus-pwd.c5
-rw-r--r--nis/nss_nisplus/nisplus-rpc.c5
-rw-r--r--nis/nss_nisplus/nisplus-service.c5
-rw-r--r--nptl/ChangeLog32
-rw-r--r--nptl/Makefile2
-rw-r--r--nptl/allocatestack.c24
-rw-r--r--nptl/descr.h45
-rw-r--r--nptl/init.c28
-rw-r--r--nptl/pthreadP.h31
-rw-r--r--nptl/pthread_create.c46
-rw-r--r--nptl/pthread_mutex_consistent.c2
-rw-r--r--nptl/pthread_mutex_destroy.c12
-rw-r--r--nptl/pthread_mutex_init.c17
-rw-r--r--nptl/pthread_mutex_lock.c50
-rw-r--r--nptl/pthread_mutex_timedlock.c44
-rw-r--r--nptl/pthread_mutex_trylock.c51
-rw-r--r--nptl/pthread_mutex_unlock.c16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h4
-rw-r--r--nptl/tst-robust8.c264
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_llrintl.c168
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_llroundl.c158
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/fprsave.S18
-rw-r--r--sysdeps/powerpc/powerpc32/gprsave0.S19
-rw-r--r--sysdeps/powerpc/powerpc64/dl-trampoline.S2
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_llrintl.S94
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_llroundl.S167
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_lrintl.S2
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_lroundl.S2
-rw-r--r--sysdeps/powerpc/powerpc64/memcpy.S3
-rw-r--r--sysdeps/sparc/sparc32/bits/atomic.h2
-rw-r--r--sysdeps/sparc/sparc32/sparcv9/bits/atomic.h4
-rw-r--r--sysdeps/sparc/sparc64/bits/atomic.h6
-rw-r--r--sysdeps/unix/sysv/linux/alpha/getcontext.S4
-rw-r--r--sysdeps/unix/sysv/linux/bits/poll.h6
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h39
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S4
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S4
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S5
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/poll.h9
-rw-r--r--wcsmbs/wchar.h14
58 files changed, 2018 insertions, 855 deletions
diff --git a/ChangeLog b/ChangeLog
index 8943e8ccd7..1efd878662 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,139 @@
+2006-03-27 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/kernel-features.h: Remove support for
+ architectures which moved to ports.
+
+ * sysdeps/unix/sysv/linux/kernel-features.h: Add
+ __ASSUME_SET_ROBUST_LIST.
+
+2006-03-27 Jakub Jelinek <jakub@redhat.com>
+
+ * wcsmbs/wchar.h (btowc, wctob): Don't optimize in C++.
+
+2006-03-24 David S. Miller <davem@sunset.davemloft.net>
+
+ * sysdeps/sparc/sparc32/bits/atomic.h
+ (__v9_compare_and_exchange_val_32_acq): Add "memory" clobber.
+ * sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
+ (__arch_compare_and_exchange_val_32_acq, atomic_exchange_acq):
+ Likewise.
+ * sysdeps/sparc/sparc64/bits/atomic.h
+ (__arch_compare_and_exchange_val_32_acq,
+ __arch_compare_and_exchange_val_64_acq, atomic_exchange_acq): Likewise.
+
+2006-03-24 Jakub Jelinek <jakub@redhat.com>
+
+ * nis/nss_nisplus/nisplus-proto.c (_nss_create_tablename): Check the
+ return value of malloc rather than the static var again.
+ * nis/nss_nisplus/nisplus-grp.c (_nss_create_tablename): Likewise.
+ * nis/nss_nisplus/nisplus-network.c (_nss_create_tablename): Likewise.
+ * nis/nss_nisplus/nisplus-ethers.c (_nss_create_tablename): Likewise.
+ * nis/nss_nisplus/nisplus-rpc.c (_nss_create_tablename): Likewise.
+ * nis/nss_nisplus/nisplus-service.c (_nss_create_tablename): Likewise.
+ * nis/nss_nisplus/nisplus-hosts.c (_nss_create_tablename): Likewise.
+ * nis/nss_nisplus/nisplus-alias.c (_nss_create_tablename): Likewise.
+ * nis/nss_nisplus/nisplus-pwd.c (_nss_pwd_create_tablename): Likewise.
+
+2006-03-25 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/sparc/bits/poll.h: Add POLLMSG,
+ POLLREMOVE, and POLLRDHUP.
+ * sysdeps/unix/sysv/linux/bits/poll.h: Add POLLREMOVE and POLLRDHUP.
+
+2006-03-24 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/sparc/bits/fcntl.h: Define
+ LINUX_FADV_ASYNC_WRITE and LINUX_FADV_WRITE_WAIT.
+ * sysdeps/unix/sysv/linux/ia64/bits/fcntl.h: Likewise.
+ * sysdeps/unix/sysv/linux/sh/bits/fcntl.h: Likewise.
+ * sysdeps/unix/sysv/linux/i386/bits/fcntl.h: Likewise.
+ * sysdeps/unix/sysv/linux/s390/bits/fcntl.h: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h: Likewise.
+ * sysdeps/unix/sysv/linux/alpha/bits/fcntl.h: Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h: Likewise.
+
+2006-03-17 Roland McGrath <roland@redhat.com>
+
+ * elf/rtld.c (dl_main): Run final self-relocation after setting up TLS.
+ From Alexandre Oliva <aoliva@redhat.com>.
+
+ * elf/tst-audit2.c: New file.
+ * elf/Makefile (tests): Add it.
+ ($(objpfx)tst-audit2.out): New target.
+ (tst-audit2-ENV): New variable.
+
+ * elf/tst-leaks1.c: Include <stdio.h>.
+
+2006-03-16 Roland McGrath <roland@redhat.com>
+
+ * sysdeps/unix/sysv/linux/alpha/getcontext.S (__getcontext_x):
+ Use .set noat to quiet assembler warning.
+
+ * math/gen-libm-test.pl (parse_args): Take function name for pretty
+ output as an argument.
+ (generate_testfile): Pass it the name given in the START macro.
+
+ [BZ #2466]
+ * math/libm-test.inc (llrint_test, llround_test): Fix last change to
+ protect large-precision cases with [LDBL_MANT_DIG > 100].
+ (llrint_test_tonearest, llrint_test_towardzero): Likewise.
+ (llrint_test_downward, llrint_test_upward): Likewise.
+
+2006-03-15 Steven Munroe <sjmunroe@us.ibm.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ [BZ #2466]
+ * math/libm-test.inc (llrint_test, llround_test) [TEST_LDOUBLE]:
+ Add new test values.
+ (llrint_test_tonearest, llrint_test_towardzero, llrint_test_downward,
+ llrint_test_upward): New functions.
+ (main): Call them.
+
+ * sysdeps/ieee754/ldbl-128ibm/s_llrintl.c (__llrintl): Handle
+ rounding that spans doubles in IBM long double format.
+ * sysdeps/ieee754/ldbl-128ibm/s_llroundl.c (__llroundl): Likewise.
+ * sysdeps/powerpc/powerpc64/fpu/s_llrintl.S: Removed.
+ * sysdeps/powerpc/powerpc64/fpu/s_llroundl.S: Removed.
+ * sysdeps/powerpc/powerpc64/fpu/s_lrintl.S: Removed.
+ * sysdeps/powerpc/powerpc64/fpu/s_lroundl.S: Removed.
+
+2006-03-16 Roland McGrath <roland@redhat.com>
+
+ * wcsmbs/wchar.h (__wcstol_internal, __wcstoul_internal): Declare these
+ only when we will use them, under [__OPTIMIZE__ && __GNUC__ >= 2].
+ (__wcstoll_internal, __wcstoull_internal_defined): Likewise.
+
+2006-03-06 Steven Munroe <sjmunroe@us.ibm.com>
+
+ * sysdeps/powerpc/powerpc32/fpu/fprsave.S: Add cfi_offset for spilling
+ of non-volatile floating-point registers to the stack (fp14-fp31).
+ * sysdeps/powerpc/powerpc32/gprsave0.S: Add cfi_offset for spilling of
+ non-volatile general-purpose registers to the stack (gpr13-gpr31).
+ * sysdeps/powerpc/powerpc64/dl-trampoline.S: Add cfi_offset
+ for non-volatiles gpr30 - grp31 spilled to the stack.
+ * sysdeps/powerpc/powerpc64/memcpy.S: Add cfi_offset for non-volatile
+ gpr31 spill to the stack.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S:
+ Add cfi_offset for non-volatile gpr31 spill to the stack.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Add cfi_offset
+ for non-volatiles gpr28 - grp31 spilled to the stack.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S: Add
+ cfi_adjust_cfa_offset when a frame is stacked.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S:
+ (__novec_setcontext) : Add cfi_offset for non-volatile gpr31 spill
+ add LR saved to the stack. Add cfi_adjust_cfa_offset when frame is
+ stacked.
+ (__setcontext) : Add cfi_offset for non-volatile gpr31 spill to
+ the stack.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S:
+ (__novec_swapcontext) : Add cfi_offset for non-volatile gpr31 spill
+ add LR saved to the stack.
+ (__swapcontext) : Add cfi_offset for non-volatile gpr31 spill add LR
+ saved to the stack. Add cfi_adjust_cfa_offset when frame is stacked.
+
2006-03-07 Jakub Jelinek <jakub@redhat.com>
+ [BZ #2423]
* math/libm-test.inc [TEST_LDOUBLE] (ceil_test, floor_test, rint_test,
round_test, trunc_test): Only run some of the new tests if
LDBL_MANT_DIG > 100.
@@ -7,36 +141,50 @@
2006-03-03 Steven Munroe <sjmunroe@us.ibm.com>
Alan Modra <amodra@bigpond.net.au>
- [BZ #2423]
- * math/libm-test.inc [TEST_LDOUBLE] (ceil_test, floor_test, rint_test,
- round_test, trunc_test): Add new tests.
-
* sysdeps/powerpc/fpu/fenv_libc.h (__fegetround, __fesetround):
Define inline implementations.
* sysdeps/powerpc/fpu/fegetround.c: Use __fegetround.
* sysdeps/powerpc/fpu/fesetround.c: Use __fesetround.
+ * sysdeps/powerpc/fpu/math_ldbl.h: New file.
+
+ [BZ #2423]
+ * math/libm-test.inc [TEST_LDOUBLE] (ceil_test, floor_test, rint_test,
+ round_test, trunc_test): Add new tests.
* sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
- (EXTRACT_IBM_EXTENDED_MANTISSA, INSERT_IBM_EXTENDED_MANTISSA):
- Removed, replaced with.
+ (EXTRACT_IBM_EXTENDED_MANTISSA, INSERT_IBM_EXTENDED_MANTISSA):
+ Removed, replaced with ...
(ldbl_extract_mantissa, ldbl_insert_mantissa, ldbl_pack, ldbl_unpack,
- ldbl_canonicalise, ldbl_nearbyint): Define inline utility
- functions for IBM long double format.
+ ldbl_canonicalise, ldbl_nearbyint): New functions.
* sysdeps/ieee754/ldbl-128ibm/e_fmodl.c (__ieee754_fmodl): Replace
EXTRACT_IBM_EXTENDED_MANTISSA and INSERT_IBM_EXTENDED_MANTISSA
with ldbl_extract_mantissa and ldbl_insert_mantissa.
* sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c (__ieee754_rem_pio2l):
Replace EXTRACT_IBM_EXTENDED_MANTISSA with ldbl_extract_mantissa.
- (ldbl_extract_mantissa, ldbl_insert_mantissa): Defined.
-
+ (ldbl_extract_mantissa, ldbl_insert_mantissa): New inline functions.
* sysdeps/ieee754/ldbl-128ibm/s_ceill.c (__ceill): Handle rounding
that spans doubles in IBM long double format.
* sysdeps/ieee754/ldbl-128ibm/s_floorl.c: Likewise.
* sysdeps/ieee754/ldbl-128ibm/s_rintl.c: Likewise.
* sysdeps/ieee754/ldbl-128ibm/s_roundl.c: Likewise.
* sysdeps/ieee754/ldbl-128ibm/s_truncl.c: Likewise.
- * sysdeps/powerpc/fpu/math_ldbl.h: New file.
- * sysdeps/powerpc/powerpc64/fpu/s_rintl.S: Removed.
+ * sysdeps/powerpc/powerpc64/fpu/s_rintl.S: File removed.
+
+2004-12-09 Randolph Chung <tausq@debian.org>
+
+ * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_UTIMES): Don't
+ define for hppa, which doesn't support this syscall.
+
+2006-03-13 Jakub Jelinek <jakub@redhat.com>
+
+ [BZ #2451]
+ * elf/dl-load.c (open_verify): Add free_name argument, if true, free
+ name before calling lose.
+ (open_path): Adjust caller.
+ (_dl_map_object): Adjust callers. Free name_copy before calling
+ _dl_signal_error.
+ * elf/Makefile: Add rules to build and run tst-leaks1.
+ * elf/tst-leaks1.c: New test.
2006-03-06 Roland McGrath <roland@redhat.com>
diff --git a/elf/Makefile b/elf/Makefile
index 791341758e..3b4ef26d45 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -91,7 +91,7 @@ distribute := rtld-Rules \
order2mod1.c order2mod2.c order2mod3.c order2mod4.c \
tst-stackguard1.c tst-stackguard1-static.c \
tst-array5.c tst-array5-static.c tst-array5dep.c \
- tst-array5.exp
+ tst-array5.exp tst-leaks1.c
CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
@@ -139,7 +139,7 @@ vpath %.c ../locale/programs
endif
endif
-tests = tst-tls1 tst-tls2 tst-tls9
+tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1
ifeq (yes,$(have-initfini-array))
tests += tst-array1 tst-array2 tst-array3 tst-array4 tst-array5
endif
@@ -168,7 +168,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
tst-dlmodcount tst-dlopenrpath tst-deep1 \
tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
- unload3 unload4 unload5 unload6 tst-audit1 tst-global1 order2 \
+ unload3 unload4 unload5 unload6 tst-global1 order2 \
+ tst-audit1 tst-audit2 \
tst-stackguard1
# reldep9
test-srcs = tst-pathopt
@@ -180,6 +181,7 @@ endif
ifeq (yesyes,$(have-fpie)$(build-shared))
tests: $(objpfx)tst-pie1.out
endif
+tests: $(objpfx)tst-leaks1-mem
modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
testobj1_1 failobj constload2 constload3 unloadmod \
dep1 dep2 dep3 dep4 $(modules-vis-$(have-protected)) \
@@ -878,6 +880,9 @@ $(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so
$(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so
tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
+$(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so
+tst-audit2-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
+
$(objpfx)tst-global1: $(libdl)
$(objpfx)tst-global1.out: $(objpfx)testobj6.so $(objpfx)testobj2.so
@@ -895,3 +900,9 @@ order2mod2.so-no-z-defs = yes
tst-stackguard1-ARGS = --command "$(built-program-cmd) --child"
tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child"
+
+$(objpfx)tst-leaks1: $(libdl)
+$(objpfx)tst-leaks1-mem: $(objpfx)tst-leaks1.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@
+
+tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace
diff --git a/elf/dl-load.c b/elf/dl-load.c
index bba1c83ba0..088954a04f 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1,5 +1,6 @@
/* Map in a shared object's segments from the file.
- Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+ 2005, 2006 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
@@ -1554,7 +1555,7 @@ print_search_path (struct r_search_path_elem **list,
user might want to know about this. */
static int
open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
- int whatcode, bool *found_other_class)
+ int whatcode, bool *found_other_class, bool free_name)
{
/* This is the expected ELF header. */
#define ELF32_CLASS ELFCLASS32
@@ -1635,6 +1636,12 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
errstring = (errval == 0
? N_("file too short") : N_("cannot read file data"));
call_lose:
+ if (free_name)
+ {
+ char *realname = (char *) name;
+ name = strdupa (realname);
+ free (realname);
+ }
lose (errval, fd, name, NULL, NULL, errstring);
}
@@ -1821,7 +1828,8 @@ open_path (const char *name, size_t namelen, int preloaded,
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
_dl_debug_printf (" trying file=%s\n", buf);
- fd = open_verify (buf, fbp, loader, whatcode, found_other_class);
+ fd = open_verify (buf, fbp, loader, whatcode, found_other_class,
+ false);
if (this_dir->status[cnt] == unknown)
{
if (fd != -1)
@@ -2098,7 +2106,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
{
fd = open_verify (cached,
&fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
- LA_SER_CONFIG, &found_other_class);
+ LA_SER_CONFIG, &found_other_class, false);
if (__builtin_expect (fd != -1, 1))
{
realname = local_strdup (cached);
@@ -2136,7 +2144,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
{
fd = open_verify (realname, &fb,
loader ?: GL(dl_ns)[nsid]._ns_loaded, 0,
- &found_other_class);
+ &found_other_class, true);
if (__builtin_expect (fd, 0) == -1)
free (realname);
}
@@ -2166,8 +2174,11 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
if ((name_copy = local_strdup (name)) == NULL
|| (l = _dl_new_object (name_copy, name, type, loader,
mode, nsid)) == NULL)
- _dl_signal_error (ENOMEM, name, NULL,
- N_("cannot create shared object descriptor"));
+ {
+ free (name_copy);
+ _dl_signal_error (ENOMEM, name, NULL,
+ N_("cannot create shared object descriptor"));
+ }
/* Signal that this is a faked entry. */
l->l_faked = 1;
/* Since the descriptor is initialized with zero we do not
diff --git a/elf/rtld.c b/elf/rtld.c
index 76d129a0a0..68fe809700 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1,5 +1,5 @@
/* Run time dynamic linker.
- Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1995-2002, 2003, 2004, 2005, 2006 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
@@ -2200,7 +2200,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
#ifndef HP_TIMING_NONAVAIL
hp_timing_t start;
hp_timing_t stop;
- hp_timing_t add;
#endif
/* If we are profiling we also must do lazy reloaction. */
@@ -2255,19 +2254,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
if (__builtin_expect (GL(dl_profile_map) != NULL, 0))
/* We must prepare the profiling. */
_dl_start_profile ();
-
- if (rtld_multiple_ref)
- {
- /* There was an explicit ref to the dynamic linker as a shared lib.
- Re-relocate ourselves with user-controlled symbol definitions. */
- HP_TIMING_NOW (start);
- /* Mark the link map as not yet relocated again. */
- GL(dl_rtld_map).l_relocated = 0;
- _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
- HP_TIMING_NOW (stop);
- HP_TIMING_DIFF (add, start, stop);
- HP_TIMING_ACCUM_NT (relocate_time, add);
- }
}
#ifndef NONTLS_INIT_TP
@@ -2296,6 +2282,30 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
NONTLS_INIT_TP;
#endif
+ if (! prelinked && rtld_multiple_ref)
+ {
+ /* There was an explicit ref to the dynamic linker as a shared lib.
+ Re-relocate ourselves with user-controlled symbol definitions.
+
+ We must do this after TLS initialization in case after this
+ re-relocation, we might call a user-supplied function
+ (e.g. calloc from _dl_relocate_object) that uses TLS data. */
+
+#ifndef HP_TIMING_NONAVAIL
+ hp_timing_t start;
+ hp_timing_t stop;
+ hp_timing_t add;
+#endif
+
+ HP_TIMING_NOW (start);
+ /* Mark the link map as not yet relocated again. */
+ GL(dl_rtld_map).l_relocated = 0;
+ _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
+ HP_TIMING_NOW (stop);
+ HP_TIMING_DIFF (add, start, stop);
+ HP_TIMING_ACCUM_NT (relocate_time, add);
+ }
+
#ifdef SHARED
/* Auditing checkpoint: we have added all objects. */
if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
diff --git a/elf/tst-audit2.c b/elf/tst-audit2.c
new file mode 100644
index 0000000000..fd089b6f64
--- /dev/null
+++ b/elf/tst-audit2.c
@@ -0,0 +1,50 @@
+/* Test case for early TLS initialization in dynamic linker. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE___THREAD
+# define MAGIC1 0xabcdef72
+# define MAGIC2 0xd8675309
+static __thread unsigned int magic[] = { MAGIC1, MAGIC2 };
+#endif
+
+#undef calloc
+
+/* This calloc definition will be called by the dynamic linker itself.
+ We test that it has initialized our TLS block by the time it does so. */
+
+void *
+calloc (size_t n, size_t m)
+{
+#if HAVE___THREAD
+ if (magic[0] != MAGIC1 || magic[1] != MAGIC2)
+ {
+ printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC1, MAGIC2);
+ abort ();
+ }
+ magic[0] = MAGIC2;
+ magic[1] = MAGIC1;
+#endif
+
+ n *= m;
+ void *ptr = malloc (n);
+ if (ptr != NULL)
+ memset (ptr, '\0', n);
+ return ptr;
+}
+
+int
+main (void)
+{
+#if HAVE___THREAD
+ if (magic[1] != MAGIC1 || magic[0] != MAGIC2)
+ {
+ printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC2, MAGIC1);
+ return 1;
+ }
+#endif
+
+ return 0;
+}
diff --git a/elf/tst-leaks1.c b/elf/tst-leaks1.c
new file mode 100644
index 0000000000..36e4aee9cf
--- /dev/null
+++ b/elf/tst-leaks1.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <dlfcn.h>
+#include <mcheck.h>
+#include <stdlib.h>
+
+int
+main (void)
+{
+ mtrace ();
+
+ int ret = 0;
+ for (int i = 0; i < 10; i++)
+ {
+ void *h = dlopen (i < 5 ? "./tst-leaks1.c"
+ : "$ORIGIN/tst-leaks1.o", RTLD_LAZY);
+ if (h != NULL)
+ {
+ puts ("dlopen unexpectedly succeeded");
+ ret = 1;
+ dlclose (h);
+ }
+ }
+
+ return ret;
+}
diff --git a/fedora/branch.mk b/fedora/branch.mk
index e3f3348c17..9f35fe0f79 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
glibc-base := HEAD
DIST_BRANCH := devel
COLLECTION := dist-fc4
-fedora-sync-date := 2006-03-06 12:39 UTC
-fedora-sync-tag := fedora-glibc-20060306T1239
+fedora-sync-date := 2006-03-28 09:00 UTC
+fedora-sync-tag := fedora-glibc-20060328T0900
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index c3c2c0de58..987ee270cb 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 4
+%define glibcrelease 5
%define auxarches i586 i686 athlon sparcv9 alphaev6
%define prelinkarches noarch
%define xenarches i686 athlon
@@ -1336,6 +1336,12 @@ rm -f *.filelist*
%endif
%changelog
+* Tue Mar 28 Jakub Jelinek <jakub@redhat.com> 2.4-5
+- update from CVS
+ - pshared robust mutex support
+ - fix btowc and bwtoc in C++ (#186410)
+ - fix NIS+ (#186592)
+ - don't declare __wcsto*l_internal for non-GCC or if not -O1+ (#185667)
- don't mention nscd failures on 2.0 kernels (#185335)
* Tue Mar 7 2006 Roland McGrath <roland@redhat.com> 2.4-4
diff --git a/math/gen-libm-test.pl b/math/gen-libm-test.pl
index 26f819a884..a63f62a1cb 100755
--- a/math/gen-libm-test.pl
+++ b/math/gen-libm-test.pl
@@ -1,5 +1,5 @@
#!/usr/bin/perl -w
-# Copyright (C) 1999 Free Software Foundation, Inc.
+# Copyright (C) 1999, 2006 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Andreas Jaeger <aj@suse.de>, 1999.
@@ -234,7 +234,7 @@ sub special_functions {
# Parse the arguments to TEST_x_y
sub parse_args {
- my ($file, $descr, $args) = @_;
+ my ($file, $descr, $fct, $args) = @_;
my (@args, $str, $descr_args, $descr_res, @descr);
my ($current_arg, $cline, $i);
my ($pre, $post, @special);
@@ -248,7 +248,7 @@ sub parse_args {
@args = split /,\s*/, $args;
- $call = "$args[0] (";
+ $call = "$fct (";
# Generate first the string that's shown to the user
$current_arg = 1;
@@ -423,7 +423,7 @@ sub parse_args {
sub generate_testfile {
my ($input, $output) = @_;
my ($lasttext);
- my (@args, $i, $str);
+ my (@args, $i, $str, $thisfct);
open INPUT, $input or die ("Can't open $input: $!");
open OUTPUT, ">$output" or die ("Can't open $output: $!");
@@ -436,11 +436,12 @@ sub generate_testfile {
my ($descr, $args);
chop;
($descr, $args) = ($_ =~ /TEST_(\w+)\s*\((.*)\)/);
- &parse_args (\*OUTPUT, $descr, $args);
+ &parse_args (\*OUTPUT, $descr, $thisfct, $args);
next;
}
# START (function)
if (/START/) {
+ ($thisfct) = ($_ =~ /START\s*\((.*)\)/);
print OUTPUT " init_max_error ();\n";
next;
}
diff --git a/math/libm-test.inc b/math/libm-test.inc
index b144796f2a..58ab2f5e59 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -3331,6 +3331,22 @@ llrint_test (void)
TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL);
TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL);
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL);
+#endif
+
TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL);
TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
@@ -3343,6 +3359,22 @@ llrint_test (void)
TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL);
TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL);
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL);
+#endif
+
TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL);
TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
@@ -3354,11 +3386,570 @@ llrint_test (void)
TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL);
TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
#endif
END (llrint);
}
+static void
+llrint_test_tonearest (void)
+{
+ int save_round_mode;
+ START (llrint_tonearest);
+
+ save_round_mode = fegetround ();
+
+ if (!fesetround (FE_TONEAREST))
+ {
+ TEST_f_L (llrint, 0.0, 0);
+ TEST_f_L (llrint, minus_zero, 0);
+ TEST_f_L (llrint, 0.2L, 0);
+ TEST_f_L (llrint, -0.2L, 0);
+
+ TEST_f_L (llrint, 1.4L, 1);
+ TEST_f_L (llrint, -1.4L, -1);
+
+ TEST_f_L (llrint, 8388600.3L, 8388600);
+ TEST_f_L (llrint, -8388600.3L, -8388600);
+
+ TEST_f_l (llrint, 1071930.0008, 1071930);
+
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llrint, 2097151.0,2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llrint, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llrint, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llrint, 4503599627370495.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.75L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370497.5L, 4503599627370498LL);
+
+ TEST_f_L (llrint, -4503599627370495.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL);
+#endif
+
+ TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.75L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5L, 9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL);
+#endif
+
+ TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.75L, 72057594037927937LL);
+ TEST_f_L (llrint, 72057594037927937.5L, 72057594037927938LL);
+
+ TEST_f_L (llrint, -72057594037927935.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL);
+ TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+ }
+
+ fesetround (save_round_mode);
+
+ END (llrint_tonearest);
+}
+
+static void
+llrint_test_towardzero (void)
+{
+ int save_round_mode;
+ START (llrint_towardzero);
+
+ save_round_mode = fegetround ();
+
+ if (!fesetround (FE_TOWARDZERO))
+ {
+ TEST_f_L (llrint, 0.0, 0);
+ TEST_f_L (llrint, minus_zero, 0);
+ TEST_f_L (llrint, 0.2L, 0);
+ TEST_f_L (llrint, -0.2L, 0);
+
+ TEST_f_L (llrint, 1.4L, 1);
+ TEST_f_L (llrint, -1.4L, -1);
+
+ TEST_f_L (llrint, 8388600.3L, 8388600);
+ TEST_f_L (llrint, -8388600.3L, -8388600);
+
+ TEST_f_l (llrint, 1071930.0008, 1071930);
+
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llrint, 2097151.0,2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llrint, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llrint, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llrint, 4503599627370495.5L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.75L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.5L, 4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.5L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.75L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.5L, -4503599627370497LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370494LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370496LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370494LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370496LL);
+#endif
+
+ TEST_f_L (llrint, 9007199254740991.5L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.75L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.5L, 9007199254740993LL);
+
+ TEST_f_L (llrint, -9007199254740991.5L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.75L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.5L, -9007199254740993LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740993LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740993LL);
+#endif
+
+ TEST_f_L (llrint, 72057594037927935.5L, 72057594037927935LL);
+ TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.75L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927937.5L, 72057594037927937LL);
+
+ TEST_f_L (llrint, -72057594037927935.5L, -72057594037927935LL);
+ TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.75L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927937.5L, -72057594037927937LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775805LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775805LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+ }
+
+ fesetround (save_round_mode);
+
+ END (llrint_towardzero);
+}
+
+static void
+llrint_test_downward (void)
+{
+ int save_round_mode;
+ START (llrint_downward);
+
+ save_round_mode = fegetround ();
+
+ if (!fesetround (FE_DOWNWARD))
+ {
+ TEST_f_L (llrint, 0.0, 0);
+ TEST_f_L (llrint, minus_zero, 0);
+ TEST_f_L (llrint, 0.2L, 0);
+ TEST_f_L (llrint, -0.2L, -1);
+
+ TEST_f_L (llrint, 1.4L, 1);
+ TEST_f_L (llrint, -1.4L, -2);
+
+ TEST_f_L (llrint, 8388600.3L, 8388600);
+ TEST_f_L (llrint, -8388600.3L, -8388601);
+
+ TEST_f_l (llrint, 1071930.0008, 1071930);
+
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llrint, 2097151.0,2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llrint, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llrint, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llrint, 4503599627370495.5L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.75L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.5L, 4503599627370497LL);
+
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370494LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370496LL);
+
+ TEST_f_L (llrint, -4503599627370495.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.25L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370496.5L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370498LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL);
+
+ TEST_f_L (llrint, 9007199254740991.5L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.75L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.5L, 9007199254740993LL);
+
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740993LL);
+
+ TEST_f_L (llrint, -9007199254740991.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.25L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740992.5L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740994LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL);
+
+ TEST_f_L (llrint, 72057594037927935.5L, 72057594037927935LL);
+ TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.75L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927937.5L, 72057594037927937LL);
+
+ TEST_f_L (llrint, -72057594037927935.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.25L, -72057594037927937LL);
+ TEST_f_L (llrint, -72057594037927936.5L, -72057594037927937LL);
+ TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL);
+ TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775805LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+ }
+
+ fesetround (save_round_mode);
+
+ END (llrint_downward);
+}
+
+static void
+llrint_test_upward (void)
+{
+ int save_round_mode;
+ START (llrint_upward);
+
+ save_round_mode = fegetround ();
+
+ if (!fesetround (FE_UPWARD))
+ {
+ TEST_f_L (llrint, 0.0, 0);
+ TEST_f_L (llrint, minus_zero, 0);
+ TEST_f_L (llrint, 0.2L, 1);
+ TEST_f_L (llrint, -0.2L, 0);
+
+ TEST_f_L (llrint, 1.4L, 2);
+ TEST_f_L (llrint, -1.4L, -1);
+
+ TEST_f_L (llrint, 8388600.3L, 8388601);
+ TEST_f_L (llrint, -8388600.3L, -8388600);
+#ifndef TEST_FLOAT
+ TEST_f_l (llrint, 1071930.0008, 1071931);
+#endif
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llrint, 2097151.0,2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llrint, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llrint, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llrint, 4503599627370495.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.25L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370496.5L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370496.75L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370497.5L, 4503599627370498LL);
+
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370498LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.5L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.75L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.5L, -4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370494LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370496LL);
+
+ TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.25L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740992.5L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740992.75L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5L, 9007199254740994LL);
+
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740994LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.5L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.75L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.5L, -9007199254740993LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740993LL);
+
+ TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.25L, 72057594037927937LL);
+ TEST_f_L (llrint, 72057594037927936.5L, 72057594037927937LL);
+ TEST_f_L (llrint, 72057594037927936.75L, 72057594037927937LL);
+ TEST_f_L (llrint, 72057594037927937.5L, 72057594037927938LL);
+
+ TEST_f_L (llrint, -72057594037927935.5L, -72057594037927935LL);
+ TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.75L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927937.5L, -72057594037927937LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775805LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775807L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+ }
+
+ fesetround (save_round_mode);
+
+ END (llrint_upward);
+}
+
static void
log_test (void)
@@ -3597,6 +4188,22 @@ llround_test (void)
TEST_f_L (llround, 4503599627370496.75L, 4503599627370497LL);
TEST_f_L (llround, 4503599627370497.5L, 4503599627370498LL);
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llround, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llround, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llround, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llround, 4503599627370494.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llround, 4503599627370495.5000000000001L, 4503599627370496LL);
+ TEST_f_L (llround, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+ TEST_f_L (llround, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llround, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llround, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llround, -4503599627370494.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llround, -4503599627370495.5000000000001L, -4503599627370496LL);
+ TEST_f_L (llround, -4503599627370496.5000000000001L, -4503599627370497LL);
+# endif
+
TEST_f_L (llround, -4503599627370495.5L, -4503599627370496LL);
TEST_f_L (llround, -4503599627370496.25L, -4503599627370496LL);
TEST_f_L (llround, -4503599627370496.5L, -4503599627370497LL);
@@ -3609,6 +4216,22 @@ llround_test (void)
TEST_f_L (llround, 9007199254740992.75L, 9007199254740993LL);
TEST_f_L (llround, 9007199254740993.5L, 9007199254740994LL);
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llround, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llround, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llround, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llround, 9007199254740991.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llround, 9007199254740992.5000000000001L, 9007199254740993LL);
+ TEST_f_L (llround, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+ TEST_f_L (llround, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llround, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llround, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llround, -9007199254740991.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llround, -9007199254740992.5000000000001L, -9007199254740993LL);
+ TEST_f_L (llround, -9007199254740993.5000000000001L, -9007199254740994LL);
+# endif
+
TEST_f_L (llround, -9007199254740991.5L, -9007199254740992LL);
TEST_f_L (llround, -9007199254740992.25L, -9007199254740992LL);
TEST_f_L (llround, -9007199254740992.5L, -9007199254740993LL);
@@ -4051,6 +4674,12 @@ rint_test (void)
TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
# endif
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
+# endif
+
TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L);
TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
@@ -4077,6 +4706,26 @@ rint_test (void)
TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
# endif
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
+# endif
+
TEST_f_f (rint, 9007199254740991.5L, 9007199254740992.0L);
TEST_f_f (rint, 9007199254740992.25L, 9007199254740992.0L);
TEST_f_f (rint, 9007199254740992.5L, 9007199254740992.0L);
@@ -4117,66 +4766,66 @@ rint_test_tonearest (void)
int save_round_mode;
START (rint_tonearest);
- save_round_mode = fegetround();
+ save_round_mode = fegetround ();
if (!fesetround (FE_TONEAREST))
- {
- TEST_f_f (rint, 2.0, 2.0);
- TEST_f_f (rint, 1.5, 2.0);
- TEST_f_f (rint, 1.0, 1.0);
- TEST_f_f (rint, 0.5, 0.0);
- TEST_f_f (rint, 0.0, 0.0);
- TEST_f_f (rint, minus_zero, minus_zero);
- TEST_f_f (rint, -0.5, -0.0);
- TEST_f_f (rint, -1.0, -1.0);
- TEST_f_f (rint, -1.5, -2.0);
- TEST_f_f (rint, -2.0, -2.0);
- TEST_f_f (rint, 0.1, 0.0);
- TEST_f_f (rint, 0.25, 0.0);
- TEST_f_f (rint, 0.625, 1.0);
- TEST_f_f (rint, -0.1, -0.0);
- TEST_f_f (rint, -0.25, -0.0);
- TEST_f_f (rint, -0.625, -1.0);
+ {
+ TEST_f_f (rint, 2.0, 2.0);
+ TEST_f_f (rint, 1.5, 2.0);
+ TEST_f_f (rint, 1.0, 1.0);
+ TEST_f_f (rint, 0.5, 0.0);
+ TEST_f_f (rint, 0.0, 0.0);
+ TEST_f_f (rint, minus_zero, minus_zero);
+ TEST_f_f (rint, -0.5, -0.0);
+ TEST_f_f (rint, -1.0, -1.0);
+ TEST_f_f (rint, -1.5, -2.0);
+ TEST_f_f (rint, -2.0, -2.0);
+ TEST_f_f (rint, 0.1, 0.0);
+ TEST_f_f (rint, 0.25, 0.0);
+ TEST_f_f (rint, 0.625, 1.0);
+ TEST_f_f (rint, -0.1, -0.0);
+ TEST_f_f (rint, -0.25, -0.0);
+ TEST_f_f (rint, -0.625, -1.0);
#ifdef TEST_LDOUBLE
- /* The result can only be represented in long double. */
- TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L);
- TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L);
+ /* The result can only be represented in long double. */
+ TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L);
# if LDBL_MANT_DIG > 100
- TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L);
- TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
# endif
- TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L);
- TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L);
+ TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L);
# if LDBL_MANT_DIG > 100
- TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L);
- TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L);
-
- TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
- TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
- TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
- TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L);
- TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L);
- TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L);
-
- TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
- TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
- TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
- TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L);
- TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L);
- TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
# endif
#endif
- }
+ }
- fesetround(save_round_mode);
+ fesetround (save_round_mode);
END (rint_tonearest);
}
@@ -4187,66 +4836,66 @@ rint_test_towardzero (void)
int save_round_mode;
START (rint_towardzero);
- save_round_mode = fegetround();
+ save_round_mode = fegetround ();
if (!fesetround (FE_TOWARDZERO))
- {
- TEST_f_f (rint, 2.0, 2.0);
- TEST_f_f (rint, 1.5, 1.0);
- TEST_f_f (rint, 1.0, 1.0);
- TEST_f_f (rint, 0.5, 0.0);
- TEST_f_f (rint, 0.0, 0.0);
- TEST_f_f (rint, minus_zero, minus_zero);
- TEST_f_f (rint, -0.5, -0.0);
- TEST_f_f (rint, -1.0, -1.0);
- TEST_f_f (rint, -1.5, -1.0);
- TEST_f_f (rint, -2.0, -2.0);
- TEST_f_f (rint, 0.1, 0.0);
- TEST_f_f (rint, 0.25, 0.0);
- TEST_f_f (rint, 0.625, 0.0);
- TEST_f_f (rint, -0.1, -0.0);
- TEST_f_f (rint, -0.25, -0.0);
- TEST_f_f (rint, -0.625, -0.0);
+ {
+ TEST_f_f (rint, 2.0, 2.0);
+ TEST_f_f (rint, 1.5, 1.0);
+ TEST_f_f (rint, 1.0, 1.0);
+ TEST_f_f (rint, 0.5, 0.0);
+ TEST_f_f (rint, 0.0, 0.0);
+ TEST_f_f (rint, minus_zero, minus_zero);
+ TEST_f_f (rint, -0.5, -0.0);
+ TEST_f_f (rint, -1.0, -1.0);
+ TEST_f_f (rint, -1.5, -1.0);
+ TEST_f_f (rint, -2.0, -2.0);
+ TEST_f_f (rint, 0.1, 0.0);
+ TEST_f_f (rint, 0.25, 0.0);
+ TEST_f_f (rint, 0.625, 0.0);
+ TEST_f_f (rint, -0.1, -0.0);
+ TEST_f_f (rint, -0.25, -0.0);
+ TEST_f_f (rint, -0.625, -0.0);
#ifdef TEST_LDOUBLE
- /* The result can only be represented in long double. */
- TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L);
- TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L);
+ /* The result can only be represented in long double. */
+ TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L);
# if LDBL_MANT_DIG > 100
- TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L);
- TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L);
- TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L);
# endif
- TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L);
- TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L);
# if LDBL_MANT_DIG > 100
- TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L);
- TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L);
- TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L);
-
- TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
- TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
- TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
- TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L);
- TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L);
- TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L);
-
- TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
- TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
- TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
- TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L);
- TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L);
- TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L);
# endif
#endif
- }
+ }
- fesetround(save_round_mode);
+ fesetround (save_round_mode);
END (rint_towardzero);
}
@@ -4257,66 +4906,66 @@ rint_test_downward (void)
int save_round_mode;
START (rint_downward);
- save_round_mode = fegetround();
+ save_round_mode = fegetround ();
if (!fesetround (FE_DOWNWARD))
- {
- TEST_f_f (rint, 2.0, 2.0);
- TEST_f_f (rint, 1.5, 1.0);
- TEST_f_f (rint, 1.0, 1.0);
- TEST_f_f (rint, 0.5, 0.0);
- TEST_f_f (rint, 0.0, 0.0);
- TEST_f_f (rint, minus_zero, minus_zero);
- TEST_f_f (rint, -0.5, -1.0);
- TEST_f_f (rint, -1.0, -1.0);
- TEST_f_f (rint, -1.5, -2.0);
- TEST_f_f (rint, -2.0, -2.0);
- TEST_f_f (rint, 0.1, 0.0);
- TEST_f_f (rint, 0.25, 0.0);
- TEST_f_f (rint, 0.625, 0.0);
- TEST_f_f (rint, -0.1, -1.0);
- TEST_f_f (rint, -0.25, -1.0);
- TEST_f_f (rint, -0.625, -1.0);
+ {
+ TEST_f_f (rint, 2.0, 2.0);
+ TEST_f_f (rint, 1.5, 1.0);
+ TEST_f_f (rint, 1.0, 1.0);
+ TEST_f_f (rint, 0.5, 0.0);
+ TEST_f_f (rint, 0.0, 0.0);
+ TEST_f_f (rint, minus_zero, minus_zero);
+ TEST_f_f (rint, -0.5, -1.0);
+ TEST_f_f (rint, -1.0, -1.0);
+ TEST_f_f (rint, -1.5, -2.0);
+ TEST_f_f (rint, -2.0, -2.0);
+ TEST_f_f (rint, 0.1, 0.0);
+ TEST_f_f (rint, 0.25, 0.0);
+ TEST_f_f (rint, 0.625, 0.0);
+ TEST_f_f (rint, -0.1, -1.0);
+ TEST_f_f (rint, -0.25, -1.0);
+ TEST_f_f (rint, -0.625, -1.0);
#ifdef TEST_LDOUBLE
- /* The result can only be represented in long double. */
- TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L);
- TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L);
+ /* The result can only be represented in long double. */
+ TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L);
# if LDBL_MANT_DIG > 100
- TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L);
- TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L);
- TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L);
# endif
- TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.25L, -4503599627370497.0L);
- TEST_f_f (rint, -4503599627370496.5L, -4503599627370497.0L);
- TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L);
- TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L);
+ TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.25L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370496.5L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L);
# if LDBL_MANT_DIG > 100
- TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L);
- TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L);
-
- TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
- TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
- TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
- TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L);
- TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L);
- TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L);
-
- TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740992.0L);
- TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740993.0L);
- TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740994.0L);
- TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L);
- TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L);
- TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740994.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
# endif
#endif
- }
+ }
- fesetround(save_round_mode);
+ fesetround (save_round_mode);
END (rint_downward);
}
@@ -4327,66 +4976,66 @@ rint_test_upward (void)
int save_round_mode;
START (rint_upward);
- save_round_mode = fegetround();
+ save_round_mode = fegetround ();
if (!fesetround (FE_UPWARD))
- {
- TEST_f_f (rint, 2.0, 2.0);
- TEST_f_f (rint, 1.5, 2.0);
- TEST_f_f (rint, 1.0, 1.0);
- TEST_f_f (rint, 0.5, 1.0);
- TEST_f_f (rint, 0.0, 0.0);
- TEST_f_f (rint, minus_zero, minus_zero);
- TEST_f_f (rint, -0.5, -0.0);
- TEST_f_f (rint, -1.0, -1.0);
- TEST_f_f (rint, -1.5, -1.0);
- TEST_f_f (rint, -2.0, -2.0);
- TEST_f_f (rint, 0.1, 1.0);
- TEST_f_f (rint, 0.25, 1.0);
- TEST_f_f (rint, 0.625, 1.0);
- TEST_f_f (rint, -0.1, -0.0);
- TEST_f_f (rint, -0.25, -0.0);
- TEST_f_f (rint, -0.625, -0.0);
+ {
+ TEST_f_f (rint, 2.0, 2.0);
+ TEST_f_f (rint, 1.5, 2.0);
+ TEST_f_f (rint, 1.0, 1.0);
+ TEST_f_f (rint, 0.5, 1.0);
+ TEST_f_f (rint, 0.0, 0.0);
+ TEST_f_f (rint, minus_zero, minus_zero);
+ TEST_f_f (rint, -0.5, -0.0);
+ TEST_f_f (rint, -1.0, -1.0);
+ TEST_f_f (rint, -1.5, -1.0);
+ TEST_f_f (rint, -2.0, -2.0);
+ TEST_f_f (rint, 0.1, 1.0);
+ TEST_f_f (rint, 0.25, 1.0);
+ TEST_f_f (rint, 0.625, 1.0);
+ TEST_f_f (rint, -0.1, -0.0);
+ TEST_f_f (rint, -0.25, -0.0);
+ TEST_f_f (rint, -0.625, -0.0);
#ifdef TEST_LDOUBLE
- /* The result can only be represented in long double. */
- TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.25L, 4503599627370497.0L);
- TEST_f_f (rint, 4503599627370496.5L, 4503599627370497.0L);
- TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L);
- TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L);
+ /* The result can only be represented in long double. */
+ TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.25L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370496.5L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L);
# if LDBL_MANT_DIG > 100
- TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L);
- TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
- TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
# endif
- TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L);
- TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L);
- TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L);
# if LDBL_MANT_DIG > 100
- TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L);
- TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L);
- TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L);
-
- TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740992.0L);
- TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740993.0L);
- TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740994.0L);
- TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L);
- TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L);
- TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L);
-
- TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
- TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
- TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
- TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L);
- TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L);
- TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740994.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L);
# endif
#endif
- }
+ }
- fesetround(save_round_mode);
+ fesetround (save_round_mode);
END (rint_upward);
}
@@ -4419,7 +5068,7 @@ round_test (void)
/* The result can only be represented in long double. */
TEST_f_f (round, 4503599627370495.5L, 4503599627370496.0L);
TEST_f_f (round, 4503599627370496.25L, 4503599627370496.0L);
- TEST_f_f (round, 4503599627370496.5L, 4503599627370497.0L);
+ TEST_f_f (round, 4503599627370496.5L, 4503599627370497.0L);
TEST_f_f (round, 4503599627370496.75L, 4503599627370497.0L);
TEST_f_f (round, 4503599627370497.5L, 4503599627370498.0L);
# if LDBL_MANT_DIG > 100
@@ -4428,10 +5077,10 @@ round_test (void)
TEST_f_f (round, 4503599627370496.5000000000001L, 4503599627370497.0L);
# endif
- TEST_f_f (round, -4503599627370495.5L, -4503599627370496.0L);
- TEST_f_f (round, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (round, -4503599627370495.5L, -4503599627370496.0L);
+ TEST_f_f (round, -4503599627370496.25L, -4503599627370496.0L);
TEST_f_f (round, -4503599627370496.5L, -4503599627370497.0L);
- TEST_f_f (round, -4503599627370496.75L, -4503599627370497.0L);
+ TEST_f_f (round, -4503599627370496.75L, -4503599627370497.0L);
TEST_f_f (round, -4503599627370497.5L, -4503599627370498.0L);
# if LDBL_MANT_DIG > 100
TEST_f_f (round, -4503599627370494.5000000000001L, -4503599627370495.0L);
@@ -4870,7 +5519,7 @@ trunc_test (void)
TEST_f_f (trunc, 4503599627370495.5000000000001L, 4503599627370495.0L);
TEST_f_f (trunc, 4503599627370496.5000000000001L, 4503599627370496.0L);
# endif
-
+
TEST_f_f (trunc, -4503599627370495.5L, -4503599627370495.0L);
TEST_f_f (trunc, -4503599627370496.25L, -4503599627370496.0L);
TEST_f_f (trunc, -4503599627370496.5L, -4503599627370496.0L);
@@ -4883,6 +5532,12 @@ trunc_test (void)
TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L);
# endif
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (trunc, -4503599627370494.5000000000001L, -4503599627370494.0L);
+ TEST_f_f (trunc, -4503599627370495.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L);
+# endif
+
TEST_f_f (trunc, 9007199254740991.5L, 9007199254740991.0L);
TEST_f_f (trunc, 9007199254740992.25L, 9007199254740992.0L);
TEST_f_f (trunc, 9007199254740992.5L, 9007199254740992.0L);
@@ -4929,7 +5584,7 @@ trunc_test (void)
TEST_f_f (trunc, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L);
TEST_f_f (trunc, 10141204801825835211973625643008.5L, 10141204801825835211973625643008.0L);
TEST_f_f (trunc, 10141204801825835211973625643008.75L, 10141204801825835211973625643008.0L);
- TEST_f_f (trunc, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L);
+ TEST_f_f (trunc, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L);
#endif
END (trunc);
@@ -5315,6 +5970,10 @@ main (int argc, char **argv)
rint_test_upward ();
lrint_test ();
llrint_test ();
+ llrint_test_tonearest ();
+ llrint_test_towardzero ();
+ llrint_test_downward ();
+ llrint_test_upward ();
round_test ();
lround_test ();
llround_test ();
diff --git a/nis/nss_nisplus/nisplus-alias.c b/nis/nss_nisplus/nisplus-alias.c
index 6aa93ab3bc..d7926e1566 100644
--- a/nis/nss_nisplus/nisplus-alias.c
+++ b/nis/nss_nisplus/nisplus-alias.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -51,7 +52,7 @@ _nss_create_tablename (int *errnop)
static const char prefix[] = "mail_aliases.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
- if (tablename_val == NULL)
+ if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-ethers.c b/nis/nss_nisplus/nisplus-ethers.c
index fcc550e743..ca0a9e2481 100644
--- a/nis/nss_nisplus/nisplus-ethers.c
+++ b/nis/nss_nisplus/nisplus-ethers.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997,1998,2000-2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997,1998,2000-2003,2005,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
@@ -94,7 +94,7 @@ _nss_create_tablename (int *errnop)
static const char prefix[] = "ethers.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
- if (tablename_val == NULL)
+ if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-grp.c b/nis/nss_nisplus/nisplus-grp.c
index 423f7e7291..624b20610a 100644
--- a/nis/nss_nisplus/nisplus-grp.c
+++ b/nis/nss_nisplus/nisplus-grp.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 2001, 2002, 2003, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -47,7 +48,7 @@ _nss_create_tablename (int *errnop)
static const char prefix[] = "group.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
- if (tablename_val == NULL)
+ if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c
index 81f8a984dc..bf002d6dd7 100644
--- a/nis/nss_nisplus/nisplus-hosts.c
+++ b/nis/nss_nisplus/nisplus-hosts.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997-2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2002, 2003, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
@@ -186,7 +186,7 @@ _nss_create_tablename (int *errnop)
static const char prefix[] = "hosts.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
- if (tablename_val == NULL)
+ if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-network.c b/nis/nss_nisplus/nisplus-network.c
index dc6b99e505..960c0558e9 100644
--- a/nis/nss_nisplus/nisplus-network.c
+++ b/nis/nss_nisplus/nisplus-network.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997,1998,2000-2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997,1998,2000-2003,2005,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -148,7 +148,7 @@ _nss_create_tablename (int *errnop)
static const char prefix[] = "networks.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
- if (tablename_val == NULL)
+ if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-proto.c b/nis/nss_nisplus/nisplus-proto.c
index 585a4844ad..a3370aa85e 100644
--- a/nis/nss_nisplus/nisplus-proto.c
+++ b/nis/nss_nisplus/nisplus-proto.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -147,7 +148,7 @@ _nss_create_tablename (int *errnop)
static const char prefix[] = "protocols.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
- if (tablename_val == NULL)
+ if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c
index 97679dd349..6c222ede02 100644
--- a/nis/nss_nisplus/nisplus-pwd.c
+++ b/nis/nss_nisplus/nisplus-pwd.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997,1999,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1999, 2001, 2002, 2003, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -44,7 +45,7 @@ _nss_pwd_create_tablename (int *errnop)
static const char prefix[] = "passwd.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
- if (pwd_tablename_val == NULL)
+ if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-rpc.c b/nis/nss_nisplus/nisplus-rpc.c
index 98baa5f7fc..f6ab3fbd87 100644
--- a/nis/nss_nisplus/nisplus-rpc.c
+++ b/nis/nss_nisplus/nisplus-rpc.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -144,7 +145,7 @@ _nss_create_tablename (int *errnop)
static const char prefix[] = "rpc.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
- if (tablename_val == NULL)
+ if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-service.c b/nis/nss_nisplus/nisplus-service.c
index 848e5f4dd8..c47dc09a06 100644
--- a/nis/nss_nisplus/nisplus-service.c
+++ b/nis/nss_nisplus/nisplus-service.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
@@ -151,7 +152,7 @@ _nss_create_tablename (int *errnop)
static const char prefix[] = "services.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
- if (tablename_val == NULL)
+ if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 678a419aca..64cea204e3 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,35 @@
+2006-03-27 Ulrich Drepper <drepper@redhat.com>
+
+ * allocatestack.c (allocate_stack): Always initialize robust_head.
+ * descr.h: Define struct robust_list_head.
+ (struct pthread): Use robust_list_head in robust mutex list definition.
+ Adjust ENQUEUE_MUTEX and DEQUEUE_MUTEX.
+ * init.c [!__ASSUME_SET_ROBUST_LIST] (__set_robust_list_avail): Define.
+ (__pthread_initialize_minimal_internal): Register robust_list with
+ the kernel.
+ * pthreadP.h: Remove PRIVATE_ from PTHREAD_MUTEX_ROBUST_* names.
+ Declare __set_robust_list_avail.
+ * pthread_create.c (start_thread): Register robust_list of new thread.
+ [!__ASSUME_SET_ROBUST_LIST]: If robust_list is not empty wake up
+ waiters.
+ * pthread_mutex_destroy.c: For robust mutexes don't look at the
+ number of users, it's unreliable.
+ * pthread_mutex_init.c: Allow use of pshared robust mutexes if
+ set_robust_list syscall is available.
+ * pthread_mutex_consistent.c: Adjust for PTHREAD_MUTEX_ROBUST_* rename.
+ * pthread_mutex_lock.c: Simplify robust mutex code a bit.
+ Set robust_head.list_op_pending before trying to lock a robust mutex.
+ * pthread_mutex_timedlock.c: Likewise.
+ * pthread_mutex_trylock.c: Likewise.
+ * pthread_mutex_unlock.c: Likewise for unlocking.
+ * Makefile (tests): Add tst-robust8.
+ * tst-robust8.c: New file.
+
+2006-03-08 Andreas Schwab <schwab@suse.de>
+
+ * sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
+ (DL_SYSINFO_IMPLEMENTATION): Add missing newline.
+
2006-03-05 Roland McGrath <roland@redhat.com>
* configure (libc_add_on): Disable add-on when $add_ons_automatic = yes
diff --git a/nptl/Makefile b/nptl/Makefile
index 31b5ace92e..e430b8d6cb 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -206,7 +206,7 @@ tests = tst-typesizes \
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
tst-cond20 tst-cond21 \
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
- tst-robust6 tst-robust7 \
+ tst-robust6 tst-robust7 tst-robust8 \
tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 046a2470fc..a3ed1a33d3 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -365,12 +365,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
/* The process ID is also the same as that of the caller. */
pd->pid = THREAD_GETMEM (THREAD_SELF, pid);
- /* List of robust mutexes. */
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
- pd->robust_list.__prev = &pd->robust_list;
-#endif
- pd->robust_list.__next = &pd->robust_list;
-
/* Allocate the DTV for this thread. */
if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL)
{
@@ -505,12 +499,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
/* The process ID is also the same as that of the caller. */
pd->pid = THREAD_GETMEM (THREAD_SELF, pid);
- /* List of robust mutexes. */
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
- pd->robust_list.__prev = &pd->robust_list;
-#endif
- pd->robust_list.__next = &pd->robust_list;
-
/* Allocate the DTV for this thread. */
if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL)
{
@@ -634,6 +622,18 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
stillborn thread could be canceled while the lock is taken. */
pd->lock = LLL_LOCK_INITIALIZER;
+ /* The robust mutex lists also need to be initialized
+ unconditionally because the cleanup for the previous stack owner
+ might have happened in the kernel. */
+ pd->robust_head.futex_offset = (offsetof (pthread_mutex_t, __data.__lock)
+ - offsetof (pthread_mutex_t,
+ __data.__list.__next));
+ pd->robust_head.list_op_pending = NULL;
+#ifdef __PTHREAD_MUTEX_HAVE_PREV
+ pd->robust_prev = &pd->robust_head;
+#endif
+ pd->robust_head.list = &pd->robust_head;
+
/* We place the thread descriptor at the end of the stack. */
*pdp = pd;
diff --git a/nptl/descr.h b/nptl/descr.h
index 80251b920b..f89d3240da 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -102,6 +102,15 @@ struct xid_command
};
+/* Data structure used by the kernel to find robust futexes. */
+struct robust_list_head
+{
+ void *list;
+ long int futex_offset;
+ void *list_op_pending;
+};
+
+
/* Thread descriptor data structure. */
struct pthread
{
@@ -136,25 +145,43 @@ struct pthread
/* List of robust mutexes the thread is holding. */
#ifdef __PTHREAD_MUTEX_HAVE_PREV
- __pthread_list_t robust_list;
+ void *robust_prev;
+ struct robust_list_head robust_head;
+
+ /* The list above is strange. It is basically a double linked list
+ but the pointer to the next/previous element of the list points
+ in the middle of the object, the __next element. Whenever
+ casting to __pthread_list_t we need to adjust the pointer
+ first. */
+# define QUEUE_PTR_ADJUST (offsetof (__pthread_list_t, __next))
# define ENQUEUE_MUTEX(mutex) \
do { \
- __pthread_list_t *next = THREAD_GETMEM (THREAD_SELF, robust_list.__next); \
- next->__prev = &mutex->__data.__list; \
- mutex->__data.__list.__next = next; \
- mutex->__data.__list.__prev = &THREAD_SELF->robust_list; \
- THREAD_SETMEM (THREAD_SELF, robust_list.__next, &mutex->__data.__list); \
+ __pthread_list_t *next = (THREAD_GETMEM (THREAD_SELF, robust_head.list) \
+ - QUEUE_PTR_ADJUST); \
+ next->__prev = (void *) &mutex->__data.__list.__next; \
+ mutex->__data.__list.__next = (void *) &next->__next; \
+ mutex->__data.__list.__prev = (void *) &THREAD_SELF->robust_head; \
+ THREAD_SETMEM (THREAD_SELF, robust_head.list, \
+ &mutex->__data.__list.__next); \
} while (0)
# define DEQUEUE_MUTEX(mutex) \
do { \
- mutex->__data.__list.__next->__prev = mutex->__data.__list.__prev; \
- mutex->__data.__list.__prev->__next = mutex->__data.__list.__next; \
+ __pthread_list_t *next = (__pthread_list_t *) \
+ ((char *) mutex->__data.__list.__next - QUEUE_PTR_ADJUST); \
+ next->__prev = mutex->__data.__list.__prev; \
+ __pthread_list_t *prev = (__pthread_list_t *) \
+ ((char *) mutex->__data.__list.__prev - QUEUE_PTR_ADJUST); \
+ prev->__next = mutex->__data.__list.__next; \
mutex->__data.__list.__prev = NULL; \
mutex->__data.__list.__next = NULL; \
} while (0)
#else
- __pthread_slist_t robust_list;
+ union
+ {
+ __pthread_slist_t robust_list;
+ struct robust_list_head robust_head;
+ };
# define ENQUEUE_MUTEX(mutex) \
do { \
diff --git a/nptl/init.c b/nptl/init.c
index cb63ff7a6d..4db3e0c828 100644
--- a/nptl/init.c
+++ b/nptl/init.c
@@ -60,6 +60,15 @@
size_t __static_tls_size;
size_t __static_tls_align_m1;
+#ifndef __ASSUME_SET_ROBUST_LIST
+/* Negative if we do not have the system call and we can use it. */
+int __set_robust_list_avail;
+# define set_robust_list_not_avail() \
+ __set_robust_list_avail = -1
+#else
+# define set_robust_list_not_avail() do { } while (0)
+#endif
+
/* Version of the library, used in libthread_db to detect mismatches. */
static const char nptl_version[] __attribute_used__ = VERSION;
@@ -247,10 +256,6 @@ __pthread_initialize_minimal_internal (void)
struct pthread *pd = THREAD_SELF;
INTERNAL_SYSCALL_DECL (err);
pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid);
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
- pd->robust_list.__prev = &pd->robust_list;
-#endif
- pd->robust_list.__next = &pd->robust_list;
THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]);
THREAD_SETMEM (pd, user_stack, true);
if (LLL_LOCK_INITIALIZER != 0)
@@ -259,6 +264,21 @@ __pthread_initialize_minimal_internal (void)
THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
#endif
+ /* Initialize the robust mutex data. */
+#ifdef __PTHREAD_MUTEX_HAVE_PREV
+ pd->robust_prev = &pd->robust_head;
+#endif
+ pd->robust_head.list = &pd->robust_head;
+#ifdef __NR_set_robust_list
+ pd->robust_head.futex_offset = (offsetof (pthread_mutex_t, __data.__lock)
+ - offsetof (pthread_mutex_t,
+ __data.__list.__next));
+ int res = INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
+ sizeof (struct robust_list_head));
+ if (INTERNAL_SYSCALL_ERROR_P (res, err))
+#endif
+ set_robust_list_not_avail ();
+
/* Set initial thread's stack block from 0 up to __libc_stack_end.
It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
purposes this is good enough. */
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index a4d6d1a1ae..7b3da83786 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -31,6 +31,7 @@
#include <internaltypes.h>
#include <pthread-functions.h>
#include <atomic.h>
+#include <kernel-features.h>
/* Atomic operations on TLS memory. */
@@ -60,13 +61,13 @@
/* Internal mutex type value. */
enum
{
- PTHREAD_MUTEX_ROBUST_PRIVATE_NP = 16,
- PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP
- = PTHREAD_MUTEX_ROBUST_PRIVATE_NP | PTHREAD_MUTEX_RECURSIVE_NP,
- PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP
- = PTHREAD_MUTEX_ROBUST_PRIVATE_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
- PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP
- = PTHREAD_MUTEX_ROBUST_PRIVATE_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
+ PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16,
+ PTHREAD_MUTEX_ROBUST_RECURSIVE_NP
+ = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP
+ = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP
+ = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
PTHREAD_MUTEX_PRIO_INHERIT_PRIVATE_NP = 32,
PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP = 64
};
@@ -128,6 +129,11 @@ hidden_proto (__pthread_keys)
/* Number of threads running. */
extern unsigned int __nptl_nthreads attribute_hidden;
+#ifndef __ASSUME_SET_ROBUST_LIST
+/* Negative if we do not have the system call and we can use it. */
+extern int __set_robust_list_avail attribute_hidden;
+#endif
+
/* The library can run in debugging mode where it performs a lot more
tests. */
extern int __pthread_debug attribute_hidden;
@@ -504,4 +510,15 @@ extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
# define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name);
#endif
+
+#ifndef __NR_set_robust_list
+/* XXX For the time being... Once we can rely on the kernel headers
+ having the definition remove these lines. */
+# if defined __i386__
+# define __NR_set_robust_list 311
+# elif defined __x86_64__
+# define __NR_set_robust_list 273
+# endif
+#endif
+
#endif /* pthreadP.h */
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index f3d90ecebf..71365a17e8 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -229,6 +229,19 @@ start_thread (void *arg)
/* Initialize resolver state pointer. */
__resp = &pd->res;
+#ifdef __NR_set_robust_list
+# ifndef __ASSUME_SET_ROBUST_LIST
+ if (__set_robust_list_avail >= 0)
+# endif
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ /* This call should never fail because the initial call in init.c
+ succeeded. */
+ INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
+ sizeof (struct robust_list_head));
+ }
+#endif
+
/* This is where the try/finally block should be created. For
compilers without that support we do use setjmp. */
struct pthread_unwind_buf unwind_buf;
@@ -310,35 +323,34 @@ start_thread (void *arg)
the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE. */
atomic_bit_set (&pd->cancelhandling, EXITING_BIT);
+#ifndef __ASSUME_SET_ROBUST_LIST
/* If this thread has any robust mutexes locked, handle them now. */
-#if __WORDSIZE == 64
- __pthread_list_t *robust = pd->robust_list.__next;
-#else
+# if __WORDSIZE == 64
+ void *robust = pd->robust_head.list;
+# else
__pthread_slist_t *robust = pd->robust_list.__next;
-#endif
- if (__builtin_expect (robust != &pd->robust_list, 0))
+# endif
+/* We let the kernel do the notification if it is able to do so. */
+ if (__set_robust_list_avail < 0
+ && __builtin_expect (robust != &pd->robust_head, 0))
{
do
{
struct __pthread_mutex_s *this = (struct __pthread_mutex_s *)
- ((char *) robust - offsetof (struct __pthread_mutex_s, __list));
- robust = robust->__next;
+ ((char *) robust - offsetof (struct __pthread_mutex_s,
+ __list.__next));
+ robust = *((void **) robust);
- this->__list.__next = NULL;
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
+# ifdef __PTHREAD_MUTEX_HAVE_PREV
this->__list.__prev = NULL;
-#endif
+# endif
+ this->__list.__next = NULL;
lll_robust_mutex_dead (this->__lock);
}
- while (robust != &pd->robust_list);
-
- /* Clean up so that the thread descriptor can be reused. */
- pd->robust_list.__next = &pd->robust_list;
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
- pd->robust_list.__prev = &pd->robust_list;
-#endif
+ while (robust != &pd->robust_head);
}
+#endif
/* If the thread is detached free the TCB. */
if (IS_DETACHED (pd))
diff --git a/nptl/pthread_mutex_consistent.c b/nptl/pthread_mutex_consistent.c
index 0cfe972da0..d4f287b755 100644
--- a/nptl/pthread_mutex_consistent.c
+++ b/nptl/pthread_mutex_consistent.c
@@ -26,7 +26,7 @@ pthread_mutex_consistent_np (mutex)
pthread_mutex_t *mutex;
{
/* Test whether this is a robust mutex with a dead owner. */
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_PRIVATE_NP) == 0
+ if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
|| mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT)
return EINVAL;
diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c
index 19a647a846..7829979f35 100644
--- a/nptl/pthread_mutex_destroy.c
+++ b/nptl/pthread_mutex_destroy.c
@@ -25,15 +25,9 @@ int
__pthread_mutex_destroy (mutex)
pthread_mutex_t *mutex;
{
- if (mutex->__data.__nusers != 0)
- {
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_PRIVATE_NP) != 0
- && (mutex->__data.__lock & FUTEX_OWNER_DIED) != 0
- && mutex->__data.__nusers == 1)
- goto dead_robust_mutex;
-
- return EBUSY;
- }
+ if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
+ && mutex->__data.__nusers != 0)
+ return EBUSY;
/* Set to an invalid value. */
dead_robust_mutex:
diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c
index f984d90ae4..c25e4035e5 100644
--- a/nptl/pthread_mutex_init.c
+++ b/nptl/pthread_mutex_init.c
@@ -22,7 +22,6 @@
#include <string.h>
#include "pthreadP.h"
-
static const struct pthread_mutexattr default_attr =
{
/* Default is a normal mutex, not shared between processes. */
@@ -42,10 +41,6 @@ __pthread_mutex_init (mutex, mutexattr)
imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr;
/* Sanity checks. */
- // XXX For now we cannot implement robust mutexes if they are shared.
- if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0
- && (imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_PSHARED) != 0)
- return ENOTSUP;
// XXX For now we don't support priority inherited or priority protected
// XXX mutexes.
if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
@@ -57,8 +52,18 @@ __pthread_mutex_init (mutex, mutexattr)
/* Copy the values from the attribute. */
mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
+
if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0)
- mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_PRIVATE_NP;
+ {
+#ifndef __ASSUME_SET_ROBUST_LIST
+ if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_PSHARED) != 0
+ && __set_robust_list_avail < 0)
+ return ENOTSUP;
+#endif
+
+ mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ }
+
switch ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
>> PTHREAD_MUTEXATTR_PROTOCOL_SHIFT)
{
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index dd22567c71..06eef49c71 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.c
@@ -108,25 +108,33 @@ __pthread_mutex_lock (mutex)
assert (mutex->__data.__owner == 0);
break;
- case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+ case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+ case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ &mutex->__data.__list.__next);
+
oldval = mutex->__data.__lock;
do
{
+ again:
if ((oldval & FUTEX_OWNER_DIED) != 0)
{
/* The previous owner died. Try locking the mutex. */
- int newval;
- while ((newval
- = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
- id, oldval))
- != oldval)
+ int newval = id;
+#ifdef NO_INCR
+ newval |= FUTEX_WAITERS;
+#endif
+
+ newval
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+ newval, oldval);
+
+ if (newval != oldval)
{
- if ((newval & FUTEX_OWNER_DIED) == 0)
- goto normal;
oldval = newval;
+ goto again;
}
/* We got the mutex. */
@@ -135,6 +143,7 @@ __pthread_mutex_lock (mutex)
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
ENQUEUE_MUTEX (mutex);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exit here. If we fall
through to the end of the function __nusers would be
@@ -149,18 +158,23 @@ __pthread_mutex_lock (mutex)
return EOWNERDEAD;
}
- normal:
/* Check whether we already hold the mutex. */
- if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK)
- == id, 0))
+ if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
{
if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP)
- return EDEADLK;
+ == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+ {
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ NULL);
+ return EDEADLK;
+ }
if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP)
+ == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ NULL);
+
/* Just bump the counter. */
if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
/* Overflow of the counter. */
@@ -180,6 +194,7 @@ __pthread_mutex_lock (mutex)
/* This mutex is now not recoverable. */
mutex->__data.__count = 0;
lll_mutex_unlock (mutex->__data.__lock);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
}
@@ -187,6 +202,7 @@ __pthread_mutex_lock (mutex)
mutex->__data.__count = 1;
ENQUEUE_MUTEX (mutex);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
break;
default:
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index b69caedc7c..7c48c7ce6b 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -103,25 +103,27 @@ pthread_mutex_timedlock (mutex, abstime)
}
break;
- case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+ case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+ case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ &mutex->__data.__list.__next);
+
oldval = mutex->__data.__lock;
do
{
+ again:
if ((oldval & FUTEX_OWNER_DIED) != 0)
{
/* The previous owner died. Try locking the mutex. */
- int newval;
- while ((newval
- = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
- id, oldval))
- != oldval)
+ int newval
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+ id, oldval);
+ if (newval != oldval)
{
- if ((newval & FUTEX_OWNER_DIED) == 0)
- goto normal;
oldval = newval;
+ goto again;
}
/* We got the mutex. */
@@ -130,6 +132,7 @@ pthread_mutex_timedlock (mutex, abstime)
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
ENQUEUE_MUTEX (mutex);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exist here. If we fall
through to the end of the function __nusers would be
@@ -138,18 +141,23 @@ pthread_mutex_timedlock (mutex, abstime)
return EOWNERDEAD;
}
- normal:
/* Check whether we already hold the mutex. */
- if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK)
- == id, 0))
+ if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
{
if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP)
- return EDEADLK;
+ == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+ {
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ NULL);
+ return EDEADLK;
+ }
if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP)
+ == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ NULL);
+
/* Just bump the counter. */
if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
/* Overflow of the counter. */
@@ -170,6 +178,7 @@ pthread_mutex_timedlock (mutex, abstime)
/* This mutex is now not recoverable. */
mutex->__data.__count = 0;
lll_mutex_unlock (mutex->__data.__lock);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
@@ -182,6 +191,7 @@ pthread_mutex_timedlock (mutex, abstime)
mutex->__data.__count = 1;
ENQUEUE_MUTEX (mutex);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
break;
default:
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 5a13ea6925..148a6e919f 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -77,25 +77,28 @@ __pthread_mutex_trylock (mutex)
return 0;
- case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+ case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+ case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ &mutex->__data.__list.__next);
+
oldval = mutex->__data.__lock;
do
{
+ again:
if ((oldval & FUTEX_OWNER_DIED) != 0)
{
/* The previous owner died. Try locking the mutex. */
- int newval;
- while ((newval
- = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
- id, oldval))
- != oldval)
+ int newval
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+ id, oldval);
+
+ if (newval != oldval)
{
- if ((newval & FUTEX_OWNER_DIED) == 0)
- goto normal;
oldval = newval;
+ goto again;
}
/* We got the mutex. */
@@ -104,6 +107,7 @@ __pthread_mutex_trylock (mutex)
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
ENQUEUE_MUTEX (mutex);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exist here. If we fall
through to the end of the function __nusers would be
@@ -112,18 +116,23 @@ __pthread_mutex_trylock (mutex)
return EOWNERDEAD;
}
- normal:
/* Check whether we already hold the mutex. */
- if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK)
- == id, 0))
+ if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
{
if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP)
- return EDEADLK;
+ == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+ {
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ NULL);
+ return EDEADLK;
+ }
if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP)
+ == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ NULL);
+
/* Just bump the counter. */
if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
/* Overflow of the counter. */
@@ -137,7 +146,11 @@ __pthread_mutex_trylock (mutex)
oldval = lll_robust_mutex_trylock (mutex->__data.__lock, id);
if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
- return EBUSY;
+ {
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+ return EBUSY;
+ }
robust:
if (__builtin_expect (mutex->__data.__owner
@@ -147,12 +160,14 @@ __pthread_mutex_trylock (mutex)
mutex->__data.__count = 0;
if (oldval == id)
lll_mutex_unlock (mutex->__data.__lock);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
}
while ((oldval & FUTEX_OWNER_DIED) != 0);
ENQUEUE_MUTEX (mutex);
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
mutex->__data.__owner = id;
++mutex->__data.__nusers;
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index d41eefe34c..bf9aa7625f 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -63,10 +63,12 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
lll_mutex_unlock (mutex->__data.__lock);
break;
- case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
/* Recursive mutex. */
if ((mutex->__data.__lock & FUTEX_TID_MASK)
- == THREAD_GETMEM (THREAD_SELF, tid))
+ == THREAD_GETMEM (THREAD_SELF, tid)
+ && __builtin_expect (mutex->__data.__owner
+ == PTHREAD_MUTEX_INCONSISTENT, 0))
{
if (--mutex->__data.__count != 0)
/* We still hold the mutex. */
@@ -84,9 +86,9 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
goto robust;
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_NP:
- case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP:
+ case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+ case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+ case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
if ((mutex->__data.__lock & FUTEX_TID_MASK)
!= THREAD_GETMEM (THREAD_SELF, tid)
|| ! lll_mutex_islocked (mutex->__data.__lock))
@@ -102,6 +104,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
robust:
/* Remove mutex from the list. */
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ &mutex->__data.__list.__next);
DEQUEUE_MUTEX (mutex);
mutex->__data.__owner = newowner;
@@ -111,6 +115,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
/* Unlock. */
lll_robust_mutex_unlock (mutex->__data.__lock);
+
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
break;
default:
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h b/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
index af835c44b1..525b622a68 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
@@ -1,5 +1,5 @@
/* System-specific settings for dynamic linker code. IA-64 version.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2006 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
@@ -57,7 +57,7 @@ extern int _dl_sysinfo_break attribute_hidden;
".body\n\t" \
"break 0x100000;\n\t" \
"br.ret.sptk.many b6;\n\t" \
- ".endp _dl_sysinfo_break" \
+ ".endp _dl_sysinfo_break\n\t" \
".previous");
#endif
diff --git a/nptl/tst-robust8.c b/nptl/tst-robust8.c
new file mode 100644
index 0000000000..19682e594f
--- /dev/null
+++ b/nptl/tst-robust8.c
@@ -0,0 +1,264 @@
+#include <pthread.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+
+
+
+static void prepare (void);
+#define PREPARE(argc, argv) prepare ()
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+#define TIMEOUT 3
+#include "../test-skeleton.c"
+
+
+static int fd;
+#define N 100
+
+static void
+prepare (void)
+{
+ fd = create_temp_file ("tst-robust8", NULL);
+ if (fd == -1)
+ exit (1);
+}
+
+
+#define THESIGNAL SIGKILL
+#define ROUNDS 5
+#define THREADS 9
+
+
+static const struct timespec before = { 0, 0 };
+
+
+static pthread_mutex_t *map;
+
+
+static void *
+tf (void *arg)
+{
+ long int nr = (long int) arg;
+ int fct = nr % 3;
+
+ uint8_t state[N];
+ memset (state, '\0', sizeof (state));
+
+ while (1)
+ {
+ int r = random () % N;
+ if (state[r] == 0)
+ {
+ int e;
+
+ switch (fct)
+ {
+ case 0:
+ e = pthread_mutex_lock (&map[r]);
+ if (e != 0)
+ {
+ printf ("mutex_lock of %d in thread %ld failed with %d\n",
+ r, nr, e);
+ exit (1);
+ }
+ state[r] = 1;
+ break;
+ case 1:
+ e = pthread_mutex_timedlock (&map[r], &before);
+ if (e != 0 && e != ETIMEDOUT)
+ {
+ printf ("\
+mutex_timedlock of %d in thread %ld failed with %d\n",
+ r, nr, e);
+ exit (1);
+ }
+ break;
+ default:
+ e = pthread_mutex_trylock (&map[r]);
+ if (e != 0 && e != EBUSY)
+ {
+ printf ("mutex_trylock of %d in thread %ld failed with %d\n",
+ r, nr, e);
+ exit (1);
+ }
+ break;
+ }
+
+ if (e == EOWNERDEAD)
+ pthread_mutex_consistent_np (&map[r]);
+
+ if (e == 0 || e == EOWNERDEAD)
+ state[r] = 1;
+ }
+ else
+ {
+ int e = pthread_mutex_unlock (&map[r]);
+ if (e != 0)
+ {
+ printf ("mutex_unlock of %d in thread %ld failed with %d\n",
+ r, nr, e);
+ exit (1);
+ }
+
+ state[r] = 0;
+ }
+ }
+}
+
+
+static void
+child (int round)
+{
+ for (int thread = 1; thread <= THREADS; ++thread)
+ {
+ pthread_t th;
+ if (pthread_create (&th, NULL, tf, (void *) (long int) thread) != 0)
+ {
+ printf ("cannot create thread %d in round %d\n", thread, round);
+ exit (1);
+ }
+ }
+
+ struct timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1000000000 / ROUNDS;
+ while (nanosleep (&ts, &ts) != 0)
+ /* nothing */;
+
+ /* Time to die. */
+ kill (getpid (), THESIGNAL);
+
+ /* We better never get here. */
+ abort ();
+}
+
+
+static int
+do_test (void)
+{
+ if (ftruncate (fd, N * sizeof (pthread_mutex_t)) != 0)
+ {
+ puts ("cannot size new file");
+ return 1;
+ }
+
+ map = mmap (NULL, N * sizeof (pthread_mutex_t), PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ if (map == MAP_FAILED)
+ {
+ puts ("mapping failed");
+ return 1;
+ }
+
+ pthread_mutexattr_t ma;
+ if (pthread_mutexattr_init (&ma) != 0)
+ {
+ puts ("mutexattr_init failed");
+ return 0;
+ }
+ if (pthread_mutexattr_setrobust_np (&ma, PTHREAD_MUTEX_ROBUST_NP) != 0)
+ {
+ puts ("mutexattr_setrobust failed");
+ return 1;
+ }
+ if (pthread_mutexattr_setpshared (&ma, PTHREAD_PROCESS_SHARED) != 0)
+ {
+ puts ("mutexattr_setpshared failed");
+ return 1;
+ }
+
+ for (int round = 1; round <= ROUNDS; ++round)
+ {
+ for (int n = 0; n < N; ++n)
+ {
+ int e = pthread_mutex_init (&map[n], &ma);
+ if (e == ENOTSUP)
+ {
+ puts ("cannot support pshared robust mutexes");
+ return 0;
+ }
+ if (e != 0)
+ {
+ printf ("mutex_init %d in round %d failed\n", n + 1, round);
+ return 1;
+ }
+ }
+
+ pid_t p = fork ();
+ if (p == -1)
+ {
+ printf ("fork in round %d failed\n", round);
+ return 1;
+ }
+ if (p == 0)
+ child (round);
+
+ int status;
+ if (TEMP_FAILURE_RETRY (waitpid (p, &status, 0)) != p)
+ {
+ printf ("waitpid in round %d failed\n", round);
+ return 1;
+ }
+ if (!WIFSIGNALED (status))
+ {
+ printf ("child did not die of a signal in round %d\n", round);
+ return 1;
+ }
+ if (WTERMSIG (status) != THESIGNAL)
+ {
+ printf ("child did not die of signal %d in round %d\n",
+ THESIGNAL, round);
+ return 1;
+ }
+
+ for (int n = 0; n < N; ++n)
+ {
+ int e = pthread_mutex_lock (&map[n]);
+ if (e != 0 && e != EOWNERDEAD)
+ {
+ printf ("mutex_lock %d failed in round %d\n", n + 1, round);
+ return 1;
+ }
+ }
+
+ for (int n = 0; n < N; ++n)
+ if (pthread_mutex_unlock (&map[n]) != 0)
+ {
+ printf ("mutex_unlock %d failed in round %d\n", n + 1, round);
+ return 1;
+ }
+
+ for (int n = 0; n < N; ++n)
+ {
+ int e = pthread_mutex_destroy (&map[n]);
+ if (e != 0)
+ {
+ printf ("mutex_destroy %d in round %d failed with %d\n",
+ n + 1, round, e);
+ printf("nusers = %d\n", (int) map[n].__data.__nusers);
+ return 1;
+ }
+ }
+ }
+
+ if (pthread_mutexattr_destroy (&ma) != 0)
+ {
+ puts ("mutexattr_destroy failed");
+ return 1;
+ }
+
+ if (munmap (map, N * sizeof (pthread_mutex_t)) != 0)
+ {
+ puts ("munmap failed");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c b/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c
index bacf1bee0d..7228489098 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c
@@ -22,6 +22,7 @@
when it's coded in C. */
#include <math.h>
+#include <fenv_libc.h>
#include <math_ldbl_opt.h>
#include <float.h>
#include <ieee754.h>
@@ -36,89 +37,114 @@ __llrintl (x)
long double x;
#endif
{
- static const double TWO52 = 4503599627370496.0L;
- union ibm_extended_long_double u;
- long long result = __LONG_LONG_MAX__;
+ double xh, xl;
+ long long res, hi, lo;
+ int save_round;
- u.d = x;
+ ldbl_unpack (x, &xh, &xl);
- if (fabs (u.dd[0]) < TWO52)
+ /* Limit the range of values handled by the conversion to long long.
+ We do this because we aren't sure whether that conversion properly
+ raises FE_INVALID. */
+ if (__builtin_expect
+ ((__builtin_fabs (xh) <= -(double) (-__LONG_LONG_MAX__ - 1)), 1)
+#if !defined (FE_INVALID)
+ || 1
+#endif
+ )
{
- double high = u.dd[0];
- if (high > 0.0)
- {
- high += TWO52;
- high -= TWO52;
- if (high == -0.0) high = 0.0;
- }
- else if (high < 0.0)
+ save_round = fegetround ();
+
+ if (__builtin_expect ((xh == -(double) (-__LONG_LONG_MAX__ - 1)), 0))
{
- high -= TWO52;
- high += TWO52;
- if (high == 0.0) high = -0.0;
+ /* When XH is 9223372036854775808.0, converting to long long will
+ overflow, resulting in an invalid operation. However, XL might
+ be negative and of sufficient magnitude that the overall long
+ double is in fact in range. Avoid raising an exception. In any
+ case we need to convert this value specially, because
+ the converted value is not exactly represented as a double
+ thus subtracting HI from XH suffers rounding error. */
+ hi = __LONG_LONG_MAX__;
+ xh = 1.0;
}
- result = high;
- }
- else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0)
- {
- double high, low, tau;
- long long lowint;
- /* In this case we have to round the low double and handle any
- adjustment to the high double that may be caused by rounding
- (up). This is complicated by the fact that the high double
- may already be rounded and the low double may have the
- opposite sign to compensate. */
- if (u.dd[0] > 0.0)
+ else
{
- if (u.dd[1] > 0.0)
- {
- /* If the high/low doubles are the same sign then simply
- round the low double. */
- high = u.dd[0];
- low = u.dd[1];
- }
- else if (u.dd[1] < 0.0)
- {
- /* Else the high double is pre rounded and we need to
- adjust for that. */
-
- tau = nextafter (u.dd[0], 0.0);
- tau = (u.dd[0] - tau) * 2.0;
- high = u.dd[0] - tau;
- low = u.dd[1] + tau;
- }
- low += TWO52;
- low -= TWO52;
+ hi = (long long) xh;
+ xh -= hi;
}
- else if (u.dd[0] < 0.0)
+ ldbl_canonicalize (&xh, &xl);
+
+ lo = (long long) xh;
+
+ /* Peg at max/min values, assuming that the above conversions do so.
+ Strictly speaking, we can return anything for values that overflow,
+ but this is more useful. */
+ res = hi + lo;
+
+ /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi). */
+ if (__builtin_expect (((~(hi ^ lo) & (res ^ hi)) < 0), 0))
+ goto overflow;
+
+ xh -= lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ hi = res;
+ switch (save_round)
{
- if (u.dd[1] < 0.0)
- {
- /* If the high/low doubles are the same sign then simply
- round the low double. */
- high = u.dd[0];
- low = u.dd[1];
- }
- else if (u.dd[1] > 0.0)
- {
- /* Else the high double is pre rounded and we need to
- adjust for that. */
- tau = nextafter (u.dd[0], 0.0);
- tau = (u.dd[0] - tau) * 2.0;
- high = u.dd[0] - tau;
- low = u.dd[1] + tau;
- }
- low = TWO52 - low;
- low = -(low - TWO52);
+ case FE_TONEAREST:
+ if (fabs (xh) < 0.5
+ || (fabs (xh) == 0.5
+ && ((xh > 0.0 && xl < 0.0)
+ || (xh < 0.0 && xl > 0.0)
+ || (xl == 0.0 && (res & 1) == 0))))
+ return res;
+
+ if (xh < 0.0)
+ res -= 1;
+ else
+ res += 1;
+ break;
+
+ case FE_TOWARDZERO:
+ if (res > 0 && (xh < 0.0 || (xh == 0.0 && xl < 0.0)))
+ res -= 1;
+ else if (res < 0 && (xh > 0.0 || (xh == 0.0 && xl > 0.0)))
+ res += 1;
+ return res;
+ break;
+
+ case FE_UPWARD:
+ if (xh > 0.0 || (xh == 0.0 && xl > 0.0))
+ res += 1;
+ break;
+
+ case FE_DOWNWARD:
+ if (xh < 0.0 || (xh == 0.0 && xl < 0.0))
+ res -= 1;
+ break;
}
- lowint = low;
- result = high;
- result += lowint;
+
+ if (__builtin_expect (((~(hi ^ (res - hi)) & (res ^ hi)) < 0), 0))
+ goto overflow;
+
+ return res;
}
else
- result = u.dd[0];
+ {
+ if (xh > 0.0)
+ hi = __LONG_LONG_MAX__;
+ else if (xh < 0.0)
+ hi = -__LONG_LONG_MAX__ - 1;
+ else
+ /* Nan */
+ hi = 0;
+ }
- return result;
+overflow:
+#ifdef FE_INVALID
+ feraiseexcept (FE_INVALID);
+#endif
+ return hi;
}
long_double_symbol (libm, __llrintl, llrintl);
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
index 567e7ecc07..103529d5a1 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
@@ -22,12 +22,11 @@
when it's coded in C. */
#include <math.h>
-#include <fenv.h>
+#include <fenv_libc.h>
#include <math_ldbl_opt.h>
#include <float.h>
#include <ieee754.h>
-
#ifdef __STDC__
long long
__llroundl (long double x)
@@ -37,92 +36,95 @@ __llroundl (x)
long double x;
#endif
{
- static const double TWO52 = 4503599627370496.0;
- static const double HALF = 0.5;
- int mode = fegetround();
- union ibm_extended_long_double u;
- long long result = __LONG_LONG_MAX__;
-
- u.d = x;
-
- if (fabs (u.dd[0]) < TWO52)
- {
- fesetround(FE_TOWARDZERO);
- if (u.dd[0] > 0.0)
+ double xh, xl;
+ long long res, hi, lo;
+
+ ldbl_unpack (x, &xh, &xl);
+
+ /* Limit the range of values handled by the conversion to long long.
+ We do this because we aren't sure whether that conversion properly
+ raises FE_INVALID. */
+ if (__builtin_expect
+ ((__builtin_fabs (xh) <= -(double) (-__LONG_LONG_MAX__ - 1)), 1)
+#if !defined (FE_INVALID)
+ || 1
+#endif
+ )
+ {
+ if (__builtin_expect ((xh == -(double) (-__LONG_LONG_MAX__ - 1)), 0))
{
- u.dd[0] += HALF;
- u.dd[0] += TWO52;
- u.dd[0] -= TWO52;
+ /* When XH is 9223372036854775808.0, converting to long long will
+ overflow, resulting in an invalid operation. However, XL might
+ be negative and of sufficient magnitude that the overall long
+ double is in fact in range. Avoid raising an exception. In any
+ case we need to convert this value specially, because
+ the converted value is not exactly represented as a double
+ thus subtracting HI from XH suffers rounding error. */
+ hi = __LONG_LONG_MAX__;
+ xh = 1.0;
}
- else if (u.dd[0] < 0.0)
+ else
{
- u.dd[0] = TWO52 - (u.dd[0] - HALF);
- u.dd[0] = -(u.dd[0] - TWO52);
+ hi = (long long) xh;
+ xh -= hi;
}
- fesetround(mode);
- result = u.dd[0];
- }
- else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0)
- {
- double high, low;
- long long lowint;
- /* In this case we have to round the low double and handle any
- adjustment to the high double that may be caused by rounding
- (up). This is complicated by the fact that the high double
- may already be rounded and the low double may have the
- opposite sign to compensate. */
- if (u.dd[0] > 0.0)
+ ldbl_canonicalize (&xh, &xl);
+
+ lo = (long long) xh;
+
+ /* Peg at max/min values, assuming that the above conversions do so.
+ Strictly speaking, we can return anything for values that overflow,
+ but this is more useful. */
+ res = hi + lo;
+
+ /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi). */
+ if (__builtin_expect (((~(hi ^ lo) & (res ^ hi)) < 0), 0))
+ goto overflow;
+
+ xh -= lo;
+ ldbl_canonicalize (&xh, &xl);
+
+ hi = res;
+ if (xh > 0.5)
+ {
+ res += 1;
+ }
+ else if (xh == 0.5)
{
- if (u.dd[1] > 0.0)
- {
- /* If the high/low doubles are the same sign then simply
- round the low double. */
- high = u.dd[0];
- low = u.dd[1];
- }
- else if (u.dd[1] < 0.0)
- {
- /* Else the high double is pre rounded and we need to
- adjust for that. */
- high = nextafter (u.dd[0], 0.0);
- low = u.dd[1] + (u.dd[0] - high);
- }
- fesetround(FE_TOWARDZERO);
- low += HALF;
- low += TWO52;
- low -= TWO52;
+ if (xl > 0.0 || (xl == 0.0 && res >= 0))
+ res += 1;
}
- else if (u.dd[0] < 0.0)
+ else if (-xh > 0.5)
{
- if (u.dd[1] < 0.0)
- {
- /* If the high/low doubles are the same sign then simply
- round the low double. */
- high = u.dd[0];
- low = u.dd[1];
- }
- else if (u.dd[1] > 0.0)
- {
- /* Else the high double is pre rounded and we need to
- adjust for that. */
- high = nextafter (u.dd[0], 0.0);
- low = u.dd[1] + (u.dd[0] - high);
- }
- fesetround(FE_TOWARDZERO);
- low -= HALF;
- low = TWO52 - low;
- low = -(low - TWO52);
+ res -= 1;
}
- fesetround(mode);
- lowint = low;
- result = high;
- result += lowint;
+ else if (-xh == 0.5)
+ {
+ if (xl < 0.0 || (xl == 0.0 && res <= 0))
+ res -= 1;
+ }
+
+ if (__builtin_expect (((~(hi ^ (res - hi)) & (res ^ hi)) < 0), 0))
+ goto overflow;
+
+ return res;
}
else
- {
- result = u.dd[0];
- }
- return result;
+ {
+ if (xh > 0.0)
+ hi = __LONG_LONG_MAX__;
+ else if (xh < 0.0)
+ hi = -__LONG_LONG_MAX__ - 1;
+ else
+ /* Nan */
+ hi = 0;
+ }
+
+overflow:
+#ifdef FE_INVALID
+ feraiseexcept (FE_INVALID);
+#endif
+ return hi;
}
long_double_symbol (libm, __llroundl, llroundl);
diff --git a/sysdeps/powerpc/powerpc32/fpu/fprsave.S b/sysdeps/powerpc/powerpc32/fpu/fprsave.S
index 597c3e611f..c05178775d 100644
--- a/sysdeps/powerpc/powerpc32/fpu/fprsave.S
+++ b/sysdeps/powerpc/powerpc32/fpu/fprsave.S
@@ -27,68 +27,86 @@ ENTRY(_savefpr_all)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_14)
C_TEXT(_savef14):
C_TEXT(_savefpr_14): stfd fp14,-144(r1)
+ cfi_offset(fp14,-144)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef15)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_15)
C_TEXT(_savef15):
C_TEXT(_savefpr_15): stfd fp15,-136(r1)
+ cfi_offset(fp15,-136)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef16)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_16)
C_TEXT(_savef16):
C_TEXT(_savefpr_16): stfd fp16,-128(r1)
+ cfi_offset(fp16,-128)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef17)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_17)
C_TEXT(_savef17):
C_TEXT(_savefpr_17): stfd fp17,-120(r1)
+ cfi_offset(fp17,-120)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef18)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_18)
C_TEXT(_savef18):
C_TEXT(_savefpr_18): stfd fp18,-112(r1)
+ cfi_offset(fp18,-112)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef19)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_19)
C_TEXT(_savef19):
C_TEXT(_savefpr_19): stfd fp19,-104(r1)
+ cfi_offset(fp19,-104)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef20)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_20)
C_TEXT(_savef20):
C_TEXT(_savefpr_20): stfd fp20,-96(r1)
+ cfi_offset(fp20,-96)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef21)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_21)
C_TEXT(_savef21):
C_TEXT(_savefpr_21): stfd fp21,-88(r1)
+ cfi_offset(fp21,-88)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef22)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_22)
C_TEXT(_savef22):
C_TEXT(_savefpr_22): stfd fp22,-80(r1)
+ cfi_offset(fp22,-80)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef23)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_23)
C_TEXT(_savef23):
C_TEXT(_savefpr_23): stfd fp23,-72(r1)
+ cfi_offset(fp23,-72)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef24)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_24)
C_TEXT(_savef24):
C_TEXT(_savefpr_24): stfd fp24,-64(r1)
+ cfi_offset(fp24,-64)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef25)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_25)
C_TEXT(_savef25):
C_TEXT(_savefpr_25): stfd fp25,-56(r1)
+ cfi_offset(fp25,-56)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef26)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_26)
C_TEXT(_savef26):
C_TEXT(_savefpr_26): stfd fp26,-48(r1)
+ cfi_offset(fp26,-48)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef27)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_27)
C_TEXT(_savef27):
C_TEXT(_savefpr_27): stfd fp27,-40(r1)
+ cfi_offset(fp27,-40)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef28)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_28)
C_TEXT(_savef28):
C_TEXT(_savefpr_28): stfd fp28,-32(r1)
+ cfi_offset(fp28,-32)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savef29)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_29)
C_TEXT(_savef29):
C_TEXT(_savefpr_29): stfd fp29,-24(r1) #save f29
stfd fp30,-16(r1) #save f30
stfd fp31,-8(r1) #save f31
+ cfi_offset(fp29,-24)
+ cfi_offset(fp30,-16)
+ cfi_offset(fp31,-8)
stw r0,8(r1) #save LR in callers frame
blr #return
END (_savefpr_all)
diff --git a/sysdeps/powerpc/powerpc32/gprsave0.S b/sysdeps/powerpc/powerpc32/gprsave0.S
index 8b81647dd7..c74272b56d 100644
--- a/sysdeps/powerpc/powerpc32/gprsave0.S
+++ b/sysdeps/powerpc/powerpc32/gprsave0.S
@@ -30,40 +30,59 @@
ENTRY(_savegpr0_all)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_13)
C_TEXT(_savegpr0_13): stw r13,-76(r1)
+ cfi_offset(r13,-76)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_14)
C_TEXT(_savegpr0_14): stw r14,-72(r1)
+ cfi_offset(r14,-72)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_15)
C_TEXT(_savegpr0_15): stw r15,-68(r1)
+ cfi_offset(r15,-68)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_16)
C_TEXT(_savegpr0_16): stw r16,-64(r1)
+ cfi_offset(r16,-64)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_17)
C_TEXT(_savegpr0_17): stw r17,-60(r1)
+ cfi_offset(r17,-60)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_18)
C_TEXT(_savegpr0_18): stw r18,-56(r1)
+ cfi_offset(r18,-56)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_19)
C_TEXT(_savegpr0_19): stw r19,-52(r1)
+ cfi_offset(r19,-52)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_20)
C_TEXT(_savegpr0_20): stw r20,-48(r1)
+ cfi_offset(r20,-48)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_21)
C_TEXT(_savegpr0_21): stw r21,-44(r1)
+ cfi_offset(r21,-44)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_22)
C_TEXT(_savegpr0_22): stw r22,-40(r1)
+ cfi_offset(r22,-40)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_23)
C_TEXT(_savegpr0_23): stw r23,-36(r1)
+ cfi_offset(r23,-36)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_24)
C_TEXT(_savegpr0_24): stw r24,-32(r1)
+ cfi_offset(r24,-32)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_25)
C_TEXT(_savegpr0_25): stw r25,-28(r1)
+ cfi_offset(r25,-28)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_26)
C_TEXT(_savegpr0_26): stw r26,-24(r1)
+ cfi_offset(r26,-24)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_27)
C_TEXT(_savegpr0_27): stw r27,-20(r1)
+ cfi_offset(r27,-20)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_28)
C_TEXT(_savegpr0_28): stw r28,-16(r1)
+ cfi_offset(r28,-16)
ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_29)
C_TEXT(_savegpr0_29): stw r29,-12(r1) #save r29
stw r30,-8(r1) #save r30
stw r31,-4(r1) #save r31
+ cfi_offset(r29,-12)
+ cfi_offset(r30,-8)
+ cfi_offset(r31,-4)
stw r0,8(r1) #save LR in callers frame
blr #return
END (_savegpr0_all)
diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S
index c5afe5a3fa..9ca394dda2 100644
--- a/sysdeps/powerpc/powerpc64/dl-trampoline.S
+++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S
@@ -176,7 +176,9 @@ EALIGN(_dl_profile_resolve, 4, 0)
/* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
need to call _dl_call_pltexit. */
std r31,-8(r1)
+ cfi_offset(r31,-8)
std r30,-16(r1)
+ cfi_offset(r30,-16)
/* We need to save the registers used to pass parameters, ie. r3 thru
r10; the registers are saved in a stack frame. */
stdu r1,-FRAME_SIZE(r1)
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_llrintl.S b/sysdeps/powerpc/powerpc64/fpu/s_llrintl.S
deleted file mode 100644
index aa487775d4..0000000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_llrintl.S
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Round long double to long int.
- IBM extended format long double version.
- Copyright (C) 2004,2006 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 <sysdep.h>
-#include <math_ldbl_opt.h>
-
- .section ".toc","aw"
-.LC0: /* 2**52 */
- .tc FD_43300000_0[TC],0x4330000000000000
-.LC1: /* 2**63 */
- .tc FD_43E00000_0[TC],0x43e0000000000000
- .section ".text"
-
-/* long long int[r3] __llrintl (long double x[fp1,fp2]) */
-ENTRY (__llrintl)
- lfd fp13,.LC0@toc(2)
- lfd fp10,.LC1@toc(2)
- fabs fp0,fp1
- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
- fcmpu cr6,fp0,fp10 /* if (fabs(x) > TWO63) */
- beq- cr6,.L2
- fctid fp11,fp1 /* must delay this opperation to here */
- fctid fp12,fp2 /* and avoid setting "invalid operation". */
- li r0,0
- stfd fp11,-16(r1)
- bgt- cr6,.L9 /* if > TWO63 return "invalid operation". */
- ble+ cr7,.L9 /* If < TWO52 only thy high double is used. */
- stfd fp12,-8(r1)
- nop /* Insure the following load is in a different dispatch group */
- nop /* to avoid pipe stall on POWER4&5. */
- nop
-.L8:
- ld r0,-8(r1)
-.L9:
- ld r3,-16(r1)
- add r3,r3,r0
- blr
-
-/* The high double is >= TWO63 so it looks like we are "out of range".
- But this may be caused by rounding of the high double and the
- negative low double may bring it back into range. So we need to
- de-round the high double and invert the low double without changing
- the effective long double value. To do this we compute a special
- value (tau) that we can subtract from the high double and add to
- the low double before conversion. The resulting integers can be
- summed to get the total value.
-
- tau = floor(x_high/TWO52);
- x0 = x_high - tau;
- x1 = x_low + tau; */
-.L2:
- fdiv fp8,fp1,fp13 /* x_high/TWO52 */
- fctidz fp0,fp8
- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
- fctid fp11,fp3
- fctid fp12,fp4
- stfd fp11,-16(r1)
- stfd fp12,-8(r1)
- nop /* Insure the following load is in a different dispatch group */
- nop /* to avoid pipe stall on POWER4&5. */
- nop
- ld r3,-16(r1)
- ld r0,-8(r1)
- addo. r3,r3,r0
- bnslr+ cr0 /* if the sum does not overflow, return. */
- fctid fp11,fp1 /* Otherwise we want to set "invalid operation". */
- li r0,0
- stfd fp11,-16(r1)
- b .L9
-
-END (__llrintl)
-
-strong_alias (__llrintl, __lrintl)
-long_double_symbol (libm, __llrintl, llrintl)
-long_double_symbol (libm, __lrintl, lrintl)
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_llroundl.S b/sysdeps/powerpc/powerpc64/fpu/s_llroundl.S
deleted file mode 100644
index 29eca11093..0000000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_llroundl.S
+++ /dev/null
@@ -1,167 +0,0 @@
-/* llroundl function.
- IBM extended format long double version.
- Copyright (C) 2004, 2006 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 <sysdep.h>
-#include <math_ldbl_opt.h>
-
- .section ".toc","aw"
-.LC0: /* 0.0 */
- .tc FD_00000000_0[TC],0x0000000000000000
-.LC1: /* 0.5 */
- .tc FD_3fe00000_0[TC],0x3fe0000000000000
-.LC2: /* 2**52 */
- .tc FD_43300000_0[TC],0x4330000000000000
-.LC3: /* 2**63 */
- .tc FD_43E00000_0[TC],0x43e0000000000000
- .section ".text"
-
-/* long long [r3] llround (long double x [fp1,fp2])
- IEEE 1003.1 llroundl function. IEEE specifies "round to the nearest
- integer value, rounding halfway cases away from zero, regardless of
- the current rounding mode." However PowerPC Architecture defines
- "round to Nearest" as "Choose the best approximation. In case of a
- tie, choose the one that is even (least significant bit o).".
- So we can't use the PowerPC "round to Nearest" mode. Instead we set
- "round toward Zero" mode and round by adding +-0.5 before rounding
- toward zero. The "Floating Convert To Integer Doubleword with round
- toward zero" instruction handles the conversion including the
- overflow cases and signalling "Invalid Operation".
-
- PowerPC64 long double uses the IBM extended format which is
- represented two 64-floating point double values. The values are
- non-overlapping giving an effective precision of 106 bits. The first
- double contains the high order bits of mantisa and is always rounded
- to represent a normal rounding of long double to double. Since the
- long double value is sum of the high and low values, the low double
- normally has the opposite sign to compensate for the this rounding.
-
- For long double there is 4 cases:
- 1) |x| < 2**52, all the integer bits are in the high double.
- Round and convert the high double to long long.
- 2) 2**52 <= |x|< 2**63, Still fits but need bits from both doubles.
- Round the low double, convert both, then sum the long long values.
- 3) |x| == 2**63, Looks like an overflow but may not be due to rounding
- of the high double.
- See the description following lable L2.
- 4) |x| > 2**63, This will overflow the 64-bit signed integer.
- Treat like case #1. The fctidz instruction will generate the
- appropriate and signal "invalid operation".
-
- */
-
-ENTRY (__llroundl)
- mffs fp7 /* Save current FPU rounding mode. */
- fabs fp0,fp1
- lfd fp13,.LC2@toc(2) /* 2**52 */
- lfd fp12,.LC3@toc(2) /* 2**63 */
- lfd fp11,.LC0@toc(2) /* 0.0 */
- lfd fp10,.LC1@toc(2) /* 0.5 */
- fabs fp9,fp2
- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
- fcmpu cr6,fp1,fp11 /* if (x > 0.0) */
- bnl- cr7,.L2
- mtfsfi 7,1 /* Set rounding mode toward 0. */
- ble- cr6,.L1
- fadd fp9,fp1,fp10 /* x+= 0.5; */
- b .L0
-.L1:
- fsub fp9,fp1,fp10 /* x-= 0.5; */
-.L0:
- fctid fp0,fp9
- stfd fp0,-16(r1)
- mtfsf 0x01,fp7 /* restore previous rounding mode. */
- nop /* Insure the following load is in a different dispatch group */
- nop /* to avoid pipe stall on POWER4&5. */
- nop
- ld r3,-16(r1)
- blr
-
-/* The high double is > TWO52 so we need to round the low double and
- perhaps the high double. In this case we have to round the low
- double and handle any adjustment to the high double that may be
- caused by rounding (up). This is complicated by the fact that the
- high double may already be rounded and the low double may have the
- opposite sign to compensate.This gets a bit tricky so we use the
- following algorithm:
-
- tau = trunc(x_high/TWO52);
- x0 = x_high - tau;
- x1 = x_low + tau;
- r1 = round(x1);
- y_high = x0 + r1;
- y_low = x0 - y_high + r1;
- return y; */
-.L2:
- fcmpu cr7,fp0,fp12 /* if (|x_high| > TWO63) */
- fcmpu cr0,fp9,fp11 /* || (|x_low| == 0.0) */
- fmr fp9,fp1
- fcmpu cr5,fp2,fp11 /* if (x_low > 0.0) */
- bgt- cr7,.L0 /* return llround(x); */
- mtfsfi 7,1 /* Set rounding mode toward 0. */
- fdiv fp8,fp1,fp13 /* x_high/TWO52 */
-
- bng- cr6,.L6 /* if (x > 0.0) */
- fctidz fp0,fp8
- fcfid fp8,fp0 /* tau = trunc(x_high/TWO52); */
- bng cr5,.L4 /* if (x_low > 0.0) */
- fmr fp3,fp1
- fmr fp4,fp2
- b .L5
-.L4: /* if (x_low < 0.0) */
- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
-.L5:
- fadd fp5,fp4,fp10 /* r1 = x1 + 0.5; */
- b .L9
-.L6: /* if (x < 0.0) */
- fctidz fp0,fp8
- fcfid fp8,fp0 /* tau = trunc(x_high/TWO52); */
- bnl cr5,.L7 /* if (x_low < 0.0) */
- fmr fp3,fp1
- fmr fp4,fp2
- b .L8
-.L7: /* if (x_low > 0.0) */
- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
-.L8:
- fsub fp5,fp4,fp10 /* r1 = x1 - 0.5; */
-.L9:
- fctid. fp11,fp3
- fctid fp12,fp5
- stfd fp11,-16(r1)
- stfd fp12,-8(r1)
- mtfsf 0x01,fp7 /* restore previous rounding mode. */
- nop /* Insure the following load is in a different dispatch group */
- nop /* to avoid pipe stall on POWER4&5. */
- nop
- ld r3,-16(r1)
- bunlr cr1 /* if not overflow, return. */
- ld r0,-8(r1)
- addo. r3,r3,r0
- bnslr cr0
- fmr fp9,fp12
- bng cr6,.L0
- fneg fp9,fp12
- b .L0
-END (__llroundl)
-
-strong_alias (__llroundl, __lroundl)
-long_double_symbol (libm, __llroundl, llroundl)
-long_double_symbol (libm, __lroundl, lroundl)
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_lrintl.S b/sysdeps/powerpc/powerpc64/fpu/s_lrintl.S
deleted file mode 100644
index 6c82d2e222..0000000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_lrintl.S
+++ /dev/null
@@ -1,2 +0,0 @@
-/* __lrintl is in s_llrintl.c */
-/* __lrintl is in s_llrintl.c */
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_lroundl.S b/sysdeps/powerpc/powerpc64/fpu/s_lroundl.S
deleted file mode 100644
index b24dfd8ded..0000000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_lroundl.S
+++ /dev/null
@@ -1,2 +0,0 @@
-/* __lroundl is in s_llroundl.S */
-/* __lroundl is in s_llroundl.S */
diff --git a/sysdeps/powerpc/powerpc64/memcpy.S b/sysdeps/powerpc/powerpc64/memcpy.S
index 9df5bb42b6..f395de9066 100644
--- a/sysdeps/powerpc/powerpc64/memcpy.S
+++ b/sysdeps/powerpc/powerpc64/memcpy.S
@@ -1,5 +1,5 @@
/* Optimized memcpy implementation for PowerPC64.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2006 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
@@ -43,6 +43,7 @@ EALIGN (BP_SYM (memcpy), 5, 0)
neg 0,3
std 3,-16(1)
std 31,-8(1)
+ cfi_offset(31,-8)
andi. 11,3,7 /* check alignement of dst. */
clrldi 0,0,61 /* Number of bytes until the 1st doubleword of dst. */
clrldi 10,4,61 /* check alignement of src. */
diff --git a/sysdeps/sparc/sparc32/bits/atomic.h b/sysdeps/sparc/sparc32/bits/atomic.h
index 707a4b0a52..ef553f7270 100644
--- a/sysdeps/sparc/sparc32/bits/atomic.h
+++ b/sysdeps/sparc/sparc32/bits/atomic.h
@@ -122,7 +122,7 @@ volatile unsigned char __sparc32_atomic_locks[64]
__asm __volatile (".word 0xcde05005" \
: "+r" (__acev_tmp), "=m" (*__acev_mem) \
: "r" (__acev_oldval), "m" (*__acev_mem), \
- "r" (__acev_mem)); \
+ "r" (__acev_mem) : "memory"); \
__acev_tmp; })
#endif
diff --git a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
index 36959a9926..7b9d61d468 100644
--- a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
+++ b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
@@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t;
__asm __volatile ("cas [%4], %2, %0" \
: "=r" (__acev_tmp), "=m" (*__acev_mem) \
: "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
- "0" (newval)); \
+ "0" (newval) : "memory"); \
__acev_tmp; })
/* This can be implemented if needed. */
@@ -74,7 +74,7 @@ typedef uintmax_t uatomic_max_t;
if (sizeof (*(mem)) == 4) \
__asm ("swap %0, %1" \
: "=m" (*__memp), "=r" (__oldval) \
- : "m" (*__memp), "1" (__value)); \
+ : "m" (*__memp), "1" (__value) : "memory"); \
else \
abort (); \
__oldval; })
diff --git a/sysdeps/sparc/sparc64/bits/atomic.h b/sysdeps/sparc/sparc64/bits/atomic.h
index 2fb377810e..d0a64afce8 100644
--- a/sysdeps/sparc/sparc64/bits/atomic.h
+++ b/sysdeps/sparc/sparc64/bits/atomic.h
@@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t;
__asm __volatile ("cas [%4], %2, %0" \
: "=r" (__acev_tmp), "=m" (*__acev_mem) \
: "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
- "0" (newval)); \
+ "0" (newval) : "memory"); \
__acev_tmp; })
#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
@@ -69,7 +69,7 @@ typedef uintmax_t uatomic_max_t;
__asm __volatile ("casx [%4], %2, %0" \
: "=r" (__acev_tmp), "=m" (*__acev_mem) \
: "r" ((long) (oldval)), "m" (*__acev_mem), \
- "r" (__acev_mem), "0" ((long) (newval))); \
+ "r" (__acev_mem), "0" ((long) (newval)) : "memory"); \
__acev_tmp; })
#define atomic_exchange_acq(mem, newvalue) \
@@ -80,7 +80,7 @@ typedef uintmax_t uatomic_max_t;
if (sizeof (*(mem)) == 4) \
__asm ("swap %0, %1" \
: "=m" (*__memp), "=r" (__oldval) \
- : "m" (*__memp), "1" (__value)); \
+ : "m" (*__memp), "1" (__value) : "memory"); \
else \
{ \
__val = *__memp; \
diff --git a/sysdeps/unix/sysv/linux/alpha/getcontext.S b/sysdeps/unix/sysv/linux/alpha/getcontext.S
index bf9820ac73..f010f337e6 100644
--- a/sysdeps/unix/sysv/linux/alpha/getcontext.S
+++ b/sysdeps/unix/sysv/linux/alpha/getcontext.S
@@ -1,5 +1,5 @@
/* Save current context.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 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
@@ -57,6 +57,8 @@ weak_alias (__getcontext, getcontext)
__getcontext_x:
cfi_register (64, 0)
+ .set noat
+
/* Return value of getcontext. $0 is the only register
whose value is not preserved. */
stq $31, UC_SIGCTX+SC_REGS($16)
diff --git a/sysdeps/unix/sysv/linux/bits/poll.h b/sysdeps/unix/sysv/linux/bits/poll.h
index dccb8b6665..d7996b46c5 100644
--- a/sysdeps/unix/sysv/linux/bits/poll.h
+++ b/sysdeps/unix/sysv/linux/bits/poll.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 2001, 2006 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
@@ -36,8 +36,10 @@
#endif
#ifdef __USE_GNU
-/* This is an extension for Linux. */
+/* These are extensions for Linux. */
# define POLLMSG 0x400
+# define POLLREMOVE 0x1000
+# define POLLRDHUP 0x2000
#endif
/* Event types always implicitly polled for. These bits need not be set in
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 9f3f3965f4..37d25b1a5c 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -105,10 +105,10 @@
# define __ASSUME_STAT64_SYSCALL 1
#endif
-/* On sparc and ARM the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64
+/* On sparc the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64
syscalls were introduced in 2.3.35. */
#if __LINUX_KERNEL_VERSION >= 131875 \
- && ((defined __sparc__ && !defined __arch64__) || defined __arm__)
+ && (defined __sparc__ && !defined __arch64__)
# define __ASSUME_TRUNCATE64_SYSCALL 1
# define __ASSUME_MMAP2_SYSCALL 1
# define __ASSUME_STAT64_SYSCALL 1
@@ -191,7 +191,7 @@
don't know when it got introduced). But PowerPC64 does not support
separate FCNTL64 call, FCNTL is already 64-bit */
#if __LINUX_KERNEL_VERSION >= 132100 \
- && (defined __arm__ || defined __powerpc__ || defined __sh__) \
+ && (defined __powerpc__ || defined __sh__) \
&& !defined __powerpc64__
# define __ASSUME_FCNTL64 1
#endif
@@ -260,24 +260,10 @@
#endif
/* The vfork syscall on x86 and arm was definitely available in 2.4. */
-#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __arm__)
+#if __LINUX_KERNEL_VERSION >= 132097 && defined __i386__
# define __ASSUME_VFORK_SYSCALL 1
#endif
-/* There are an infinite number of PA-RISC kernel versions numbered
- 2.4.0. But they've not really been released as such. We require
- and expect the final version here. */
-#ifdef __hppa__
-# define __ASSUME_32BITUIDS 1
-# define __ASSUME_TRUNCATE64_SYSCALL 1
-# define __ASSUME_MMAP2_SYSCALL 1
-# define __ASSUME_STAT64_SYSCALL 1
-# define __ASSUME_IPC64 1
-# define __ASSUME_ST_INO_64_BIT 1
-# define __ASSUME_FCNTL64 1
-# define __ASSUME_GETDENTS64_SYSCALL 1
-#endif
-
/* Alpha switched to a 64-bit timeval sometime before 2.2.0. */
#if __LINUX_KERNEL_VERSION >= 131584 && defined __alpha__
# define __ASSUME_TIMEVAL64 1
@@ -296,15 +282,6 @@
# define __ASSUME_CLONE_THREAD_FLAGS 1
#endif
-/* These features were surely available with 2.4.12. */
-#if __LINUX_KERNEL_VERSION >= 132108 && defined __mc68000__
-# define __ASSUME_MMAP2_SYSCALL 1
-# define __ASSUME_TRUNCATE64_SYSCALL 1
-# define __ASSUME_STAT64_SYSCALL 1
-# define __ASSUME_FCNTL64 1
-# define __ASSUME_VFORK_SYSCALL 1
-#endif
-
/* Beginning with 2.5.63 support for realtime and monotonic clocks and
timers based on them is available. */
#if __LINUX_KERNEL_VERSION >= 132415
@@ -359,7 +336,7 @@
/* The utimes syscall has been available for some architectures
forever. For x86 it was introduced after 2.5.75, for x86-64,
ppc, and ppc64 it was introduced in 2.6.0-test3. */
-#if defined __alpha__ || defined __ia64__ || defined __hppa__ \
+#if defined __alpha__ || defined __ia64__ \
|| defined __sparc__ \
|| (__LINUX_KERNEL_VERSION > 132427 && defined __i386__) \
|| (__LINUX_KERNEL_VERSION > 132609 && defined __x86_64__) \
@@ -468,3 +445,9 @@
&& (defined __i386__ || defined __x86_64__)
# define __ASSUME_ATFCTS 1
#endif
+
+/* Support for inter-process robust mutexes was added in 2.6.17. */
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+ && (defined __i386__ || defined __x86_64__)
+# define __ASSUME_SET_ROBUST_LIST 1
+#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
index 1a5251d100..40a7a24f19 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
@@ -45,6 +45,7 @@ ENTRY(__CONTEXT_FUNC_NAME)
stw r0,20(r1)
cfi_offset (lr, _FRAME_LR_SAVE)
stw r31,12(r1)
+ cfi_offset(r31,-4)
lwz r31,_UC_REGS_PTR(r3)
/*
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
index a0f018ba41..366206d286 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
@@ -52,8 +52,12 @@ ENTRY (BP_SYM (__clone))
std r29,56(r1)
std r30,64(r1)
std r31,72(r1)
+ cfi_offset(r29,-56)
+ cfi_offset(r30,-64)
+ cfi_offset(r31,-72)
#ifdef RESET_PID
std r28,48(r1)
+ cfi_offset(r28,-48)
#endif
/* Set up stack frame for child. */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
index 98b49ba1dc..8d7c959ff9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
@@ -144,6 +144,7 @@ ENTRY(__novec_getcontext)
std r0,FRAME_LR_SAVE(r1)
cfi_offset (lr, FRAME_LR_SAVE)
stdu r1,-128(r1)
+ cfi_adjust_cfa_offset(128)
li r3,ENOSYS
bl JUMPTARGET(__syscall_error)
nop
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
index 68fec9d2aa..48e9af363d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
@@ -33,6 +33,7 @@ ENTRY(__novec_setcontext)
#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
mflr r0
std r31,-8(1)
+ cfi_offset(r31,-8)
std r0,FRAME_LR_SAVE(r1)
cfi_offset (lr, FRAME_LR_SAVE)
stdu r1,-128(r1)
@@ -169,7 +170,9 @@ L(nv_do_sigret):
/* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
mflr r0
std r0,FRAME_LR_SAVE(r1)
+ cfi_offset(lr,FRAME_LR_SAVE)
stdu r1,-128(r1)
+ cfi_adjust_cfa_offset(128)
li r3,ENOSYS
bl JUMPTARGET(__syscall_error)
nop
@@ -201,6 +204,7 @@ ENTRY(__setcontext)
#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
mflr r0
std r31,-8(1)
+ cfi_offset(r31,-8)
std r0,FRAME_LR_SAVE(r1)
cfi_offset (lr, FRAME_LR_SAVE)
stdu r1,-128(r1)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
index 5a128606ad..936d641b6b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
@@ -35,6 +35,7 @@ ENTRY(__novec_swapcontext)
std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
mflr r0
std r31,-8(1)
+ cfi_offset(r31,-8)
std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
std r0,FRAME_LR_SAVE(r1)
cfi_offset (lr, FRAME_LR_SAVE)
@@ -264,6 +265,7 @@ L(nv_do_sigret):
/* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
mflr r0
std r0,FRAME_LR_SAVE(r1)
+ cfi_offset(lr,FRAME_LR_SAVE)
stdu r1,-128(r1)
li r3,ENOSYS
bl JUMPTARGET(__syscall_error)
@@ -298,11 +300,14 @@ ENTRY(__swapcontext)
std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
mflr r0
std r31,-8(1)
+ cfi_offset(r31,-8)
std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
stdu r1,-128(r1)
+ cfi_adjust_cfa_offset(128)
std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/poll.h b/sysdeps/unix/sysv/linux/sparc/bits/poll.h
index f7a7393154..53b94bc50e 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/poll.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/poll.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 2001, 2006 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
@@ -35,6 +35,13 @@
# define POLLWRBAND 0x100 /* Priority data may be written. */
#endif
+#ifdef __USE_GNU
+/* These are extensions for Linux. */
+# define POLLMSG 0x200
+# define POLLREMOVE 0x400
+# define POLLRDHUP 0x800
+#endif
+
/* Event types always implicitly polled for. These bits need not be set in
`events', but they will appear in `revents' to indicate the status of
the file descriptor. */
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index 670dc79c4a..5dc7e19345 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -321,6 +321,7 @@ __END_NAMESPACE_C99
#ifdef __USE_EXTERN_INLINES
/* Define inline function as optimization. */
+# ifndef __cplusplus
/* We can use the BTOWC and WCTOB optimizations since we know that all
locales must use ASCII encoding for the values in the ASCII range
and because the wchar_t encoding is always ISO 10646. */
@@ -335,6 +336,7 @@ extern __inline int
__NTH (wctob (wint_t __wc))
{ return (__builtin_constant_p (__wc) && __wc >= L'\0' && __wc <= L'\x7f'
? (int) __wc : __wctob_alias (__wc)); }
+# endif
extern __inline size_t
__NTH (mbrlen (__const char *__restrict __s, size_t __n,
@@ -507,26 +509,30 @@ extern long double __wcstold_internal (__const wchar_t *__restrict __nptr,
wchar_t **__restrict __endptr,
int __group) __THROW;
-#ifndef __wcstol_internal_defined
+#if !defined __wcstol_internal_defined \
+ && defined __OPTIMIZE__ && __GNUC__ >= 2
extern long int __wcstol_internal (__const wchar_t *__restrict __nptr,
wchar_t **__restrict __endptr,
int __base, int __group) __THROW;
# define __wcstol_internal_defined 1
#endif
-#ifndef __wcstoul_internal_defined
+#if !defined __wcstoul_internal_defined \
+ && defined __OPTIMIZE__ && __GNUC__ >= 2
extern unsigned long int __wcstoul_internal (__const wchar_t *__restrict __npt,
wchar_t **__restrict __endptr,
int __base, int __group) __THROW;
# define __wcstoul_internal_defined 1
#endif
-#ifndef __wcstoll_internal_defined
+#if !defined __wcstoll_internal_defined \
+ && defined __OPTIMIZE__ && __GNUC__ >= 2
__extension__
extern long long int __wcstoll_internal (__const wchar_t *__restrict __nptr,
wchar_t **__restrict __endptr,
int __base, int __group) __THROW;
# define __wcstoll_internal_defined 1
#endif
-#ifndef __wcstoull_internal_defined
+#if !defined __wcstoull_internal_defined \
+ && defined __OPTIMIZE__ && __GNUC__ >= 2
__extension__
extern unsigned long long int __wcstoull_internal (__const wchar_t *
__restrict __nptr,