commit 201e6fddc7213a7ad5eb9f9866d6fcb130d6065b
Author: Torvald Riegel <triegel@redhat.com>
Date: Fri Jan 30 19:15:31 2015 +0100
Only use 64b atomics in semaphores if long int is 64b.
@@ -34,7 +34,7 @@ __new_sem_getvalue (sem_t *sem, int *sval)
necessary, use a stronger MO here and elsewhere (e.g., potentially
release MO in all places where we consume a token). */
-#if __HAVE_64B_ATOMICS
+#if SEM_USE_64B_ATOMICS
*sval = atomic_load_relaxed (&isem->data) & SEM_VALUE_MASK;
#else
*sval = atomic_load_relaxed (&isem->value) >> SEM_VALUE_SHIFT;
@@ -53,7 +53,7 @@ __new_sem_init (sem_t *sem, int pshared, unsigned int value)
struct new_sem *isem = (struct new_sem *) sem;
/* Use the values the caller provided. */
-#if __HAVE_64B_ATOMICS
+#if SEM_USE_64B_ATOMICS
isem->data = value;
#else
isem->value = value << SEM_VALUE_SHIFT;
@@ -193,7 +193,7 @@ sem_open (const char *name, int oflag, ...)
struct new_sem newsem;
} sem;
-#if __HAVE_64B_ATOMICS
+#if SEM_USE_64B_ATOMICS
sem.newsem.data = value;
#else
sem.newsem.value = value << SEM_VALUE_SHIFT;
@@ -59,7 +59,7 @@ __new_sem_post (sem_t *sem)
struct new_sem *isem = (struct new_sem *) sem;
int private = isem->private;
-#if __HAVE_64B_ATOMICS
+#if SEM_USE_64B_ATOMICS
/* Add a token to the semaphore. We use release MO to make sure that a
thread acquiring this token synchronizes with us and other threads that
added tokens before (the release sequence includes atomic RMW operations
@@ -175,7 +175,7 @@ futex_wake (unsigned int* futex, int processes_to_wake, int private)
to previous glibc builds. */
static const int sem_assume_only_signals_cause_futex_EINTR = 1;
-#if !__HAVE_64B_ATOMICS
+#if !SEM_USE_64B_ATOMICS
static void
__sem_wait_32_finish (struct new_sem *sem);
#endif
@@ -185,7 +185,7 @@ __sem_wait_cleanup (void *arg)
{
struct new_sem *sem = (struct new_sem *) arg;
-#if __HAVE_64B_ATOMICS
+#if SEM_USE_64B_ATOMICS
/* Stop being registered as a waiter. See below for MO. */
atomic_fetch_add_relaxed (&sem->data, -((uint64_t) 1 << SEM_NWAITERS_SHIFT));
#else
@@ -204,7 +204,7 @@ do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
{
int err;
-#if __HAVE_64B_ATOMICS
+#if SEM_USE_64B_ATOMICS
err = futex_abstimed_wait ((unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0,
abstime, sem->private, true);
#else
@@ -227,7 +227,7 @@ __new_sem_wait_fast (struct new_sem *sem, int definitive_result)
synchronize memory); thus, relaxed MO is sufficient for the initial load
and the failure path of the CAS. If the weak CAS fails and we need a
definitive result, retry. */
-#if __HAVE_64B_ATOMICS
+#if SEM_USE_64B_ATOMICS
uint64_t d = atomic_load_relaxed (&sem->data);
do
{
@@ -260,7 +260,7 @@ __new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
{
int err = 0;
-#if __HAVE_64B_ATOMICS
+#if SEM_USE_64B_ATOMICS
/* Add a waiter. Relaxed MO is sufficient because we can rely on the
ordering provided by the RMW operations we use. */
uint64_t d = atomic_fetch_add_relaxed (&sem->data,
@@ -388,7 +388,7 @@ __new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
/* If there is no token, wait. */
if ((v >> SEM_VALUE_SHIFT) == 0)
{
- /* See __HAVE_64B_ATOMICS variant. */
+ /* See SEM_USE_64B_ATOMICS variant. */
err = do_futex_wait(sem, abstime);
if (err == ETIMEDOUT ||
(err == EINTR && sem_assume_only_signals_cause_futex_EINTR))
@@ -422,7 +422,7 @@ error:
}
/* Stop being a registered waiter (non-64b-atomics code only). */
-#if !__HAVE_64B_ATOMICS
+#if !SEM_USE_64B_ATOMICS
static void
__sem_wait_32_finish (struct new_sem *sem)
{
@@ -143,7 +143,17 @@ struct pthread_key_struct
/* Semaphore variable structure. */
struct new_sem
{
-#if __HAVE_64B_ATOMICS
+/* We define SEM_USE_64B_ATOMICS to 1 iff we have 64b atomic operations and
+ are on an LP64 data model. Our atomic operations expect to target
+ naturally aligned variables. sem_t is aligned to long int, so it will
+ be 64b-aligned only if long int is a 64b-sized type and naturally
+ aligned. */
+#if __HAVE_64B_ATOMICS && defined (__LP64__)
+# define SEM_USE_64B_ATOMICS 1
+#else
+# define SEM_USE_64B_ATOMICS 0
+#endif
+#if SEM_USE_64B_ATOMICS
/* The data field holds both value (in the least-significant 32 bytes) and
nwaiters. */
# if __BYTE_ORDER == __LITTLE_ENDIAN