+2007-06-06 Jakub Jelinek <jakub@redhat.com>
+
+ BZ #4586
+ * sysdeps/i386/ldbl2mpn.c (__mpn_extract_long_double): Treat
+ pseudo-zeros as zero.
+ * sysdeps/x86_64/ldbl2mpn.c: New file.
+ * sysdeps/ia64/ldbl2mpn.c: New file.
+
2007-06-04 Jakub Jelinek <jakub@redhat.com>
* sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
int cur = cmdp->cntr;
while (cur != 0)
{
- lll_futex_wait (&cmdp->cntr, cur);
+ lll_private_futex_wait (&cmdp->cntr, cur);
cur = cmdp->cntr;
}
continue;
do
- lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
+ lll_private_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
}
continue;
do
- lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
+ lll_private_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
}
__xidcmd->id[1], __xidcmd->id[2]);
if (atomic_decrement_val (&__xidcmd->cntr) == 0)
- lll_futex_wake (&__xidcmd->cntr, 1);
+ lll_private_futex_wake (&__xidcmd->cntr, 1);
/* Reset the SETXID flag. */
struct pthread *self = THREAD_SELF;
/* And release the futex. */
self->setxid_futex = 1;
- lll_futex_wake (&self->setxid_futex, 1);
+ lll_private_futex_wake (&self->setxid_futex, 1);
}
/* Low level locking macros used in NPTL implementation. Stub version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
#include <atomic.h>
-/* Implement generic mutex. Basic futex syscall support is required:
-
- lll_futex_wait(futex, value) - call sys_futex with FUTEX_WAIT
- and third parameter VALUE
-
- lll_futex_wake(futex, value) - call sys_futex with FUTEX_WAKE
- and third parameter VALUE
-*/
-
-
/* Mutex lock counter:
bit 31 clear means unlocked;
bit 31 set means locked.
if (v >= 0)
continue;
- lll_futex_wait (mutex, v);
+ lll_futex_wait (mutex, v,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
}
/* There are other threads waiting for this mutex, wake one of them
up. */
- lll_futex_wake (mutex, 1);
+ lll_futex_wake (mutex, 1,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
++ibarrier->curr_event;
/* Wake up everybody. */
- lll_futex_wake (&ibarrier->curr_event, INT_MAX);
+ lll_futex_wake (&ibarrier->curr_event, INT_MAX,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* This is the thread which finished the serialization. */
result = PTHREAD_BARRIER_SERIAL_THREAD;
/* Wait for the event counter of the barrier to change. */
do
- lll_futex_wait (&ibarrier->curr_event, event);
+ lll_futex_wait (&ibarrier->curr_event, event,
+ // XYZ check mutex flag
+ LLL_SHARED);
while (event == ibarrier->curr_event);
}
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
{
/* The requeue functionality is not available. */
wake_all:
- lll_futex_wake (&cond->__data.__futex, INT_MAX);
+ lll_futex_wake (&cond->__data.__futex, INT_MAX,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
/* That's all. */
&& cond->__data.__mutex != (void *) ~0l)
{
pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
- lll_futex_wake (&mut->__data.__lock, INT_MAX);
+ lll_futex_wake (&mut->__data.__lock, INT_MAX,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
do
{
lll_mutex_unlock (cond->__data.__lock);
- lll_futex_wait (&cond->__data.__nwaiters, nwaiters);
+ lll_futex_wait (&cond->__data.__nwaiters, nwaiters,
+ // XYZ check mutex flag
+ LLL_SHARED);
lll_mutex_lock (cond->__data.__lock);
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
/* Wake one. */
if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
- 1, &cond->__data.__lock),
+ 1, &cond->__data.__lock,
+ // XYZ check mutex flag
+ LLL_SHARED),
0))
return 0;
- lll_futex_wake (&cond->__data.__futex, 1);
+ lll_futex_wake (&cond->__data.__futex, 1,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
/* We are done. */
/* Wait until woken by signal or broadcast. */
err = lll_futex_timed_wait (&cond->__data.__futex,
- futex_val, &rt);
+ futex_val, &rt,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (cbuffer.oldtype);
and it can be successfully destroyed. */
if (cond->__data.__total_seq == -1ULL
&& cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
- lll_futex_wake (&cond->__data.__nwaiters, 1);
+ lll_futex_wake (&cond->__data.__nwaiters, 1,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* We are done with the condvar. */
lll_mutex_unlock (cond->__data.__lock);
if (cbuffer->cond->__data.__total_seq == -1ULL
&& cbuffer->cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
{
- lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1);
+ lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1,
+ // XYZ check mutex flag
+ LLL_SHARED);
destroying = 1;
}
/* Wake everybody to make sure no condvar signal gets lost. */
if (! destroying)
- lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX);
+ lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* Get the mutex before returning unless asynchronous cancellation
is in effect. */
cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. */
- lll_futex_wait (&cond->__data.__futex, futex_val);
+ lll_futex_wait (&cond->__data.__futex, futex_val,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (cbuffer.oldtype);
and it can be successfully destroyed. */
if (cond->__data.__total_seq == -1ULL
&& cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
- lll_futex_wake (&cond->__data.__nwaiters, 1);
+ lll_futex_wake (&cond->__data.__nwaiters, 1,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* We are done with the condvar. */
lll_mutex_unlock (cond->__data.__lock);
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
/* Some other thread might call any of the setXid functions and expect
us to reply. In this case wait until we did that. */
do
- lll_futex_wait (&pd->setxid_futex, 0);
+ lll_private_futex_wait (&pd->setxid_futex, 0);
while (pd->cancelhandling & SETXID_BITMASK);
/* Reset the value so that the stack can be reused. */
break;
if (oldval != ceilval)
- lll_futex_wait (&mutex->__data.__lock, ceilval | 2);
+ lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
ceilval | 2, ceilval)
/* Set current priority ceiling of pthread_mutex_t.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
break;
if (oldval != ceilval)
- lll_futex_wait (&mutex->__data.__lock, ceilval | 2);
+ lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
ceilval | 2, ceilval)
| (prioceiling << PTHREAD_MUTEX_PRIO_CEILING_SHIFT);
atomic_full_barrier ();
- lll_futex_wake (&mutex->__data.__lock, INT_MAX);
+ lll_futex_wake (&mutex->__data.__lock, INT_MAX,
+ // XYZ check mutex flag
+ LLL_SHARED);
return 0;
}
}
lll_futex_timed_wait (&mutex->__data.__lock,
- ceilval | 2, &rt);
+ ceilval | 2, &rt,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
}
while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
-/* Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
newval, oldval));
if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)
- lll_futex_wake (&mutex->__data.__lock, 1);
+ lll_futex_wake (&mutex->__data.__lock, 1,
+ // XYZ check mutex flag
+ LLL_SHARED);
int oldprio = newval >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
return __pthread_tpp_change_priority (oldprio, -1);
/* Wait for the writer to finish. */
err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup,
- waitval, &rt);
+ waitval, &rt,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* Get the lock. */
lll_mutex_lock (rwlock->__data.__lock);
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
/* Wait for the writer or reader(s) to finish. */
err = lll_futex_timed_wait (&rwlock->__data.__writer_wakeup,
- waitval, &rt);
+ waitval, &rt,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* Get the lock. */
lll_mutex_lock (rwlock->__data.__lock);
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
{
++rwlock->__data.__writer_wakeup;
lll_mutex_unlock (rwlock->__data.__lock);
- lll_futex_wake (&rwlock->__data.__writer_wakeup, 1);
+ lll_futex_wake (&rwlock->__data.__writer_wakeup, 1,
+ // XYZ check mutex flag
+ LLL_SHARED);
return 0;
}
else if (rwlock->__data.__nr_readers_queued)
{
++rwlock->__data.__readers_wakeup;
lll_mutex_unlock (rwlock->__data.__lock);
- lll_futex_wake (&rwlock->__data.__readers_wakeup, INT_MAX);
+ lll_futex_wake (&rwlock->__data.__readers_wakeup, INT_MAX,
+ // XYZ check mutex flag
+ LLL_SHARED);
return 0;
}
}
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
: "i" (offsetof (struct pthread, header.gscope_flag)), \
"0" (THREAD_GSCOPE_FLAG_UNUSED)); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 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
#define AIO_MISC_NOTIFY(waitlist) \
do { \
if (*waitlist->counterp > 0 && --*waitlist->counterp == 0) \
- lll_futex_wake (waitlist->counterp, 1); \
+ lll_private_futex_wake (waitlist->counterp, 1); \
} while (0)
#define AIO_MISC_WAIT(result, futex, timeout, cancel) \
int status; \
do \
{ \
- status = lll_futex_timed_wait (futexaddr, oldval, timeout); \
+ status = lll_private_futex_timed_wait (futexaddr, oldval, \
+ timeout); \
if (status != -EWOULDBLOCK) \
break; \
\
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 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
#define GAI_MISC_NOTIFY(waitlist) \
do { \
if (*waitlist->counterp > 0 && --*waitlist->counterp == 0) \
- lll_futex_wake (waitlist->counterp, 1); \
+ lll_private_futex_wake (waitlist->counterp, 1); \
} while (0)
#define GAI_MISC_WAIT(result, futex, timeout, cancel) \
int status; \
do \
{ \
- status = lll_futex_timed_wait (futexaddr, oldval, timeout); \
+ status = lll_private_futex_timed_wait (futexaddr, oldval, \
+ timeout); \
if (status != -EWOULDBLOCK) \
break; \
\
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
if (atomic_decrement_and_test (&allp->handler->refcntr)
&& allp->handler->need_signal)
- lll_futex_wake (allp->handler->refcntr, 1);
+ lll_private_futex_wake (allp->handler->refcntr, 1);
allp = allp->next;
}
#include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h>
+#include <kernel-features.h>
+#include <tcb-offsets.h>
#ifndef LOCK_INSTR
# ifdef UP
#define FUTEX_PRIVATE_FLAG 128
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1)
LLL_STUB_UNWIND_INFO_END
-#define lll_futex_wait(futex, val) \
+#define lll_futex_wait(futex, val, private) \
+ lll_futex_timed_wait (futex, val, NULL, private)
+
+
+#define lll_futex_timed_wait(futex, val, timeout, private) \
({ \
int __status; \
register __typeof (val) _val asm ("edx") = (val); \
LLL_ENTER_KERNEL \
LLL_EBX_LOAD \
: "=a" (__status) \
- : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (0), \
+ : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (timeout), \
"c" (FUTEX_WAIT), "d" (_val), \
"i" (offsetof (tcbhead_t, sysinfo)) \
: "memory"); \
})
-#define lll_futex_timed_wait(futex, val, timeout) \
+#define lll_futex_wake(futex, nr, private) \
+ do { \
+ int __ignore; \
+ register __typeof (nr) _nr asm ("edx") = (nr); \
+ __asm __volatile (LLL_EBX_LOAD \
+ LLL_ENTER_KERNEL \
+ LLL_EBX_LOAD \
+ : "=a" (__ignore) \
+ : "0" (SYS_futex), LLL_EBX_REG (futex), \
+ "c" (FUTEX_WAKE), "d" (_nr), \
+ "i" (0) /* phony, to align next arg's number */, \
+ "i" (offsetof (tcbhead_t, sysinfo))); \
+ } while (0)
+
+
+#define lll_private_futex_wait(futex, val) \
+ lll_private_futex_timed_wait (futex, val, NULL)
+
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define lll_private_futex_timed_wait(futex, val, timeout) \
({ \
int __status; \
register __typeof (val) _val asm ("edx") = (val); \
LLL_EBX_LOAD \
: "=a" (__status) \
: "0" (SYS_futex), LLL_EBX_REG (futex), "S" (timeout), \
- "c" (FUTEX_WAIT), "d" (_val), \
+ "c" (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)), "d" (_val), \
"i" (offsetof (tcbhead_t, sysinfo)) \
: "memory"); \
__status; \
})
-#define lll_futex_wake(futex, nr) \
+# define lll_private_futex_wake(futex, nr) \
do { \
int __ignore; \
register __typeof (nr) _nr asm ("edx") = (nr); \
LLL_EBX_LOAD \
: "=a" (__ignore) \
: "0" (SYS_futex), LLL_EBX_REG (futex), \
- "c" (FUTEX_WAKE), "d" (_nr), \
+ "c" (FUTEX_WAKE | FUTEX_PRIVATE_FLAG), "d" (_nr), \
"i" (0) /* phony, to align next arg's number */, \
"i" (offsetof (tcbhead_t, sysinfo))); \
} while (0)
+#else
+# define lll_private_futex_timed_wait(futex, val, timeout) \
+ ({ \
+ int __status; \
+ int __ignore; \
+ register __typeof (val) _val asm ("edx") = (val); \
+ __asm __volatile ("movl %%gs:%P7, %%ecx\n\t" \
+ LLL_EBX_LOAD \
+ LLL_ENTER_KERNEL \
+ LLL_EBX_LOAD \
+ : "=a" (__status), "=c" (__ignore) \
+ : LLL_EBX_REG (futex), "0" (SYS_futex), "S" (timeout), \
+ "d" (_val), "i" (offsetof (tcbhead_t, sysinfo)), \
+ "i" (PRIVATE_FUTEX) \
+ : "memory"); \
+ __status; \
+ })
+
+
+# define lll_private_futex_wake(futex, nr) \
+ do { \
+ int __ignore; \
+ int __ignore2; \
+ register __typeof (nr) _nr asm ("edx") = (nr); \
+ __asm __volatile ("orl %%gs:%P7, %%ecx\n\t" \
+ LLL_EBX_LOAD \
+ LLL_ENTER_KERNEL \
+ LLL_EBX_LOAD \
+ : "=a" (__ignore), "=c" (__ignore2) \
+ : LLL_EBX_REG (futex), "0" (SYS_futex), \
+ "1" (FUTEX_WAKE), "d" (_nr), \
+ "i" (offsetof (tcbhead_t, sysinfo)), \
+ "i" (PRIVATE_FUTEX)); \
+ } while (0)
+#endif
/* Does not preserve %eax and %ecx. */
"i" (offsetof (tcbhead_t, sysinfo))); })
-#define lll_futex_wake(futex, nr) \
- do { \
- int __ignore; \
- register __typeof (nr) _nr asm ("edx") = (nr); \
- __asm __volatile (LLL_EBX_LOAD \
- LLL_ENTER_KERNEL \
- LLL_EBX_LOAD \
- : "=a" (__ignore) \
- : "0" (SYS_futex), LLL_EBX_REG (futex), \
- "c" (FUTEX_WAKE), "d" (_nr), \
- "i" (0) /* phony, to align next arg's number */, \
- "i" (offsetof (tcbhead_t, sysinfo))); \
- } while (0)
-
-
#define lll_mutex_islocked(futex) \
(futex != 0)
{
int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);
if (oldval != 0)
- lll_futex_wait (futex, 2);
+ lll_futex_wait (futex, 2,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0);
}
/* Wait. */
int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);
if (oldval != 0)
- lll_futex_timed_wait (futex, 2, &rt);
+ lll_futex_timed_wait (futex, 2, &rt,
+ // XYZ check mutex flag
+ LLL_SHARED);
}
while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0);
if (rt.tv_sec < 0)
return ETIMEDOUT;
- /* Wait until thread terminates. */
- if (lll_futex_timed_wait (tidp, tid, &rt) == -ETIMEDOUT)
+ /* Wait until thread terminates. The kernel so far does not use
+ the private futex operations for this. */
+ if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
return ETIMEDOUT;
}
&& atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
continue;
- lll_futex_wait (futex, newval);
+ lll_futex_wait (futex, newval,
+ // XYZ check mutex flag
+ LLL_SHARED);
try:
;
&& atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
continue;
- lll_futex_timed_wait (futex, newval, &rt);
+ lll_futex_timed_wait (futex, newval, &rt,
+ // XYZ check mutex flag
+ LLL_SHARED);
try:
;
/* Defintions for lowlevel handling in ld.so.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 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
atomic_or (&(lock), __RTLD_MRLOCK_RWAIT); \
oldval |= __RTLD_MRLOCK_RWAIT; \
} \
- lll_futex_wait (lock, oldval); \
+ lll_private_futex_wait (lock, oldval); \
} \
out:; \
} while (0)
== (__RTLD_MRLOCK_INC | __RTLD_MRLOCK_WWAIT), 0)) \
/* We have to wake all threads since there might be some queued \
readers already. */ \
- lll_futex_wake (&(lock), 0x7fffffff); \
+ lll_private_futex_wake (&(lock), 0x7fffffff); \
} while (0)
} \
atomic_or (&(lock), __RTLD_MRLOCK_WWAIT); \
oldval |= __RTLD_MRLOCK_WWAIT; \
- lll_futex_wait (lock, oldval); \
+ lll_private_futex_wait (lock, oldval); \
} \
out:; \
} while (0)
do { \
int oldval = atomic_exchange_and_add (&(lock), -__RTLD_MRLOCK_WRITER); \
if (__builtin_expect ((oldval & __RTLD_MRLOCK_RWAIT) != 0, 0)) \
- lll_futex_wake (&(lock), 0x7fffffff); \
+ lll_private_futex_wake (&(lock), 0x7fffffff); \
} while (0)
int val = word; \
if (val == 0) \
break; \
- lll_futex_wait (&(word), val); \
+ lll_private_futex_wait (&(word), val); \
} \
} while (0)
#define __rtld_notify(word) \
- lll_futex_wake (&(word), 1)
+ lll_private_futex_wake (&(word), 1)
#endif
atomic_full_barrier ();
if (isem->nwaiters > 0)
{
- int err = lll_futex_wake (&isem->value, 1);
+ int err = lll_futex_wake (&isem->value, 1,
+ // XYZ check mutex flag
+ LLL_SHARED);
if (__builtin_expect (err, 0) < 0)
{
__set_errno (-err);
int *futex = (int *) sem;
int nr = atomic_increment_val (futex);
- int err = lll_futex_wake (futex, 1);
+ /* We always have to assume it is a shared semaphore. */
+ int err = lll_futex_wake (futex, 1, LLL_SHARED);
if (__builtin_expect (err, 0) < 0)
{
__set_errno (-err);
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
- err = lll_futex_timed_wait (&isem->value, 0, &rt);
+ err = lll_futex_timed_wait (&isem->value, 0, &rt,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
- err = lll_futex_wait (&isem->value, 0);
+ err = lll_futex_wait (&isem->value, 0,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
- err = lll_futex_wait (futex, 0);
+ /* Always assume the semaphore is shared. */
+ err = lll_futex_wait (futex, 0, LLL_SHARED);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
pthread_once_t *once_control = (pthread_once_t *) arg;
*once_control = 0;
- lll_futex_wake (once_control, INT_MAX);
+ lll_private_futex_wake (once_control, INT_MAX);
}
atomic_increment (once_control);
/* Wake up all other threads. */
- lll_futex_wake (once_control, INT_MAX);
+ lll_private_futex_wake (once_control, INT_MAX);
break;
}
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
++ibarrier->b.curr_event;
/* Wake up everybody. */
- lll_futex_wake (&ibarrier->b.curr_event, INT_MAX);
+ lll_futex_wake (&ibarrier->b.curr_event, INT_MAX,
+ // XYZ check mutex flag
+ LLL_SHARED);
/* This is the thread which finished the serialization. */
result = PTHREAD_BARRIER_SERIAL_THREAD;
/* Wait for the event counter of the barrier to change. */
do
- lll_futex_wait (&ibarrier->b.curr_event, event);
+ lll_futex_wait (&ibarrier->b.curr_event, event,
+ // XYZ check mutex flag
+ LLL_SHARED);
while (event == ibarrier->b.curr_event);
}
/* sem_post -- post to a POSIX semaphore. SPARC version.
- Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
nr = ++*futex;
__sparc32_atomic_do_unlock24 (futex + 1);
}
- int err = lll_futex_wake (futex, nr);
+ int err = lll_futex_wake (futex, nr,
+ // XYZ check mutex flag
+ LLL_SHARED);
if (__builtin_expect (err, 0) < 0)
{
__set_errno (-err);
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
atomic_decrement (&deleted->handler->refcntr);
unsigned int val;
while ((val = deleted->handler->refcntr) != 0)
- lll_futex_wait (&deleted->handler->refcntr, val);
+ lll_private_futex_wait (&deleted->handler->refcntr, val);
deleted = deleted->next;
}
#include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h>
+#include <kernel-features.h>
+#include <tcb-offsets.h>
#ifndef LOCK_INSTR
# ifdef UP
#define FUTEX_PRIVATE_FLAG 128
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1)
LLL_STUB_UNWIND_INFO_END
-#define lll_futex_wait(futex, val) \
+#define lll_futex_wait(futex, val, private) \
+ lll_futex_timed_wait(futex, val, NULL, private)
+
+
+#define lll_futex_timed_wait(futex, val, timeout, private) \
({ \
+ register const struct timespec *__to __asm ("r10") = timeout; \
int __status; \
register __typeof (val) _val __asm ("edx") = (val); \
- __asm __volatile ("xorq %%r10, %%r10\n\t" \
- "syscall" \
+ __asm __volatile ("syscall" \
: "=a" (__status) \
: "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT), \
- "d" (_val) \
- : "memory", "cc", "r10", "r11", "cx"); \
+ "d" (_val), "r" (__to) \
+ : "memory", "cc", "r11", "cx"); \
__status; \
})
-#define lll_futex_timed_wait(futex, val, timeout) \
+#define lll_futex_wake(futex, nr, private) \
+ do { \
+ int __ignore; \
+ register __typeof (nr) _nr __asm ("edx") = (nr); \
+ __asm __volatile ("syscall" \
+ : "=a" (__ignore) \
+ : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAKE), \
+ "d" (_nr) \
+ : "memory", "cc", "r10", "r11", "cx"); \
+ } while (0)
+
+
+#define lll_private_futex_wait(futex, val) \
+ lll_private_futex_timed_wait (futex, val, NULL)
+
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define lll_private_futex_timed_wait(futex, val, timeout) \
({ \
register const struct timespec *__to __asm ("r10") = timeout; \
int __status; \
register __typeof (val) _val __asm ("edx") = (val); \
__asm __volatile ("syscall" \
: "=a" (__status) \
- : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT), \
+ : "0" (SYS_futex), "D" (futex), \
+ "S" (FUTEX_WAIT | FUTEX_PRIVATE_FLAG), \
"d" (_val), "r" (__to) \
: "memory", "cc", "r11", "cx"); \
__status; \
})
-#define lll_futex_wake(futex, nr) \
+# define lll_private_futex_wake(futex, nr) \
do { \
int __ignore; \
register __typeof (nr) _nr __asm ("edx") = (nr); \
__asm __volatile ("syscall" \
: "=a" (__ignore) \
- : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAKE), \
+ : "0" (SYS_futex), "D" (futex), \
+ "S" (FUTEX_WAKE | FUTEX_PRIVATE_FLAG), \
"d" (_nr) \
: "memory", "cc", "r10", "r11", "cx"); \
} while (0)
+#else
+# define lll_private_futex_timed_wait(futex, val, timeout) \
+ ({ \
+ register const struct timespec *__to __asm ("r10") = timeout; \
+ int __status; \
+ int __ignore; \
+ register __typeof (val) _val __asm ("edx") = (val); \
+ __asm __volatile ("movl %%fs:%P3, %%esi\n\t" \
+ "syscall" \
+ : "=a" (__status), "=S" (__ignore) \
+ : "0" (SYS_futex), "i" (PRIVATE_FUTEX), "D" (futex), \
+ "d" (_val), "r" (__to) \
+ : "memory", "cc", "r11", "cx"); \
+ __status; \
+ })
+
+
+# define lll_private_futex_wake(futex, nr) \
+ do { \
+ int __ignore; \
+ int __ignore2; \
+ register __typeof (nr) _nr __asm ("edx") = (nr); \
+ __asm __volatile ("orl %%fs:%P3, %%esi\n\t" \
+ "syscall" \
+ : "=a" (__ignore), "=S" (__ignore2) \
+ : "0" (SYS_futex), "i" (PRIVATE_FUTEX), "D" (futex), \
+ "1" (FUTEX_WAKE), "d" (_nr) \
+ : "memory", "cc", "r10", "r11", "cx"); \
+ } while (0)
+#endif
/* Does not preserve %eax and %ecx. */
: "i" (offsetof (struct pthread, header.gscope_flag)), \
"0" (THREAD_GSCOPE_FLAG_UNUSED)); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
-/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 2000, 2007 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
#include "gmp.h"
#include "gmp-impl.h"
#include "longlong.h"
-#include "ieee754.h"
+#include <ieee754.h>
#include <float.h>
#include <stdlib.h>
#elif BITS_PER_MP_LIMB == 64
/* Hopefully the compiler will combine the two bitfield extracts
and this composition into just the original quadword extract. */
- res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+ res_ptr[0] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
#define N 1
#else
#error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
}
}
}
+ else if (u.ieee.exponent < 0x7fff
+#if N == 2
+ && res_ptr[0] == 0
+#endif
+ && res_ptr[N - 1] == 0)
+ /* Pseudo zero. */
+ *expt = 0;
return N;
}
--- /dev/null
+#include "../i386/ldbl2mpn.c"
--- /dev/null
+#include "../i386/ldbl2mpn.c"