mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-01 10:06:57 +03:00
Fix sparc semaphore implementation after recent changes.
* sysdeps/sparc/nptl/sem_init.c: Delete. * sysdeps/sparc/nptl/sem_post.c: Delete. * sysdeps/sparc/nptl/sem_timedwait.c: Delete. * sysdeps/sparc/nptl/sem_wait.c: Delete. * sysdeps/sparc/sparc32/sem_init.c: New file. * sysdeps/sparc/sparc32/sem_waitcommon.c: New file. * sysdeps/sparc/sparc32/sem_open.c: Generic nptl version with padding explicitly initialized. * sysdeps/sparc/sparc32/sem_post.c: Generic nptl version using padding for in-semaphore spinlock. * sysdeps/sparc/sparc32/sem_wait.c: Likewise. * sysdeps/sparc/sparc32/sem_trywait.c: Delete. * sysdeps/sparc/sparc32/sem_timedwait.c: Delete. * sysdeps/sparc/sparc32/sparcv9/sem_init.c: New file. * sysdeps/sparc/sparc32/sparcv9/sem_open.c: New file. * sysdeps/sparc/sparc32/sparcv9/sem_post.c: New file. * sysdeps/sparc/sparc32/sparcv9/sem_waitcommon.c: New file. * sysdeps/sparc/sparc32/sparcv9/sem_wait.c: Redirect to nptl version. * sysdeps/sparc/sparc32/sparcv9/sem_timedwait.c: Delete. * sysdeps/sparc/sparc32/sparcv9/sem_trywait.c: Delete.
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
/* sem_post -- post to a POSIX semaphore. SPARC version.
|
||||
/* sem_post -- post to a POSIX semaphore. Generic futex-using version.
|
||||
Copyright (C) 2003-2015 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
@ -17,6 +17,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <atomic.h>
|
||||
#include <errno.h>
|
||||
#include <sysdep.h>
|
||||
#include <lowlevellock.h>
|
||||
@ -24,33 +25,58 @@
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <shlib-compat.h>
|
||||
#include <sparc-nptl.h>
|
||||
|
||||
/* Wrapper for lll_futex_wake, with error checking.
|
||||
TODO Remove when cleaning up the futex API throughout glibc. */
|
||||
static __always_inline void
|
||||
futex_wake (unsigned int* futex, int processes_to_wake, int private)
|
||||
{
|
||||
int res = lll_futex_wake (futex, processes_to_wake, private);
|
||||
/* No error. Ignore the number of woken processes. */
|
||||
if (res >= 0)
|
||||
return;
|
||||
switch (res)
|
||||
{
|
||||
case -EFAULT: /* Could have happened due to memory reuse. */
|
||||
case -EINVAL: /* Could be either due to incorrect alignment (a bug in
|
||||
glibc or in the application) or due to memory being
|
||||
reused for a PI futex. We cannot distinguish between the
|
||||
two causes, and one of them is correct use, so we do not
|
||||
act in this case. */
|
||||
return;
|
||||
case -ENOSYS: /* Must have been caused by a glibc bug. */
|
||||
/* No other errors are documented at this time. */
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* See sem_wait for an explanation of the algorithm. */
|
||||
int
|
||||
__new_sem_post (sem_t *sem)
|
||||
{
|
||||
struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
|
||||
int nr;
|
||||
struct new_sem *isem = (struct new_sem *) sem;
|
||||
int private = isem->private;
|
||||
unsigned int v;
|
||||
|
||||
if (__atomic_is_v9)
|
||||
nr = atomic_increment_val (&isem->value);
|
||||
else
|
||||
__sparc32_atomic_do_lock24(&isem->pad);
|
||||
|
||||
v = isem->value;
|
||||
if ((v << SEM_VALUE_SHIFT) == SEM_VALUE_MAX)
|
||||
{
|
||||
__sparc32_atomic_do_lock24 (&isem->lock);
|
||||
nr = ++(isem->value);
|
||||
__sparc32_atomic_do_unlock24 (&isem->lock);
|
||||
}
|
||||
atomic_full_barrier ();
|
||||
if (isem->nwaiters > 0)
|
||||
{
|
||||
int err = lll_futex_wake (&isem->value, 1,
|
||||
isem->private ^ FUTEX_PRIVATE_FLAG);
|
||||
if (__builtin_expect (err, 0) < 0)
|
||||
{
|
||||
__set_errno (-err);
|
||||
return -1;
|
||||
}
|
||||
__sparc32_atomic_do_unlock24(&isem->pad);
|
||||
|
||||
__set_errno (EOVERFLOW);
|
||||
return -1;
|
||||
}
|
||||
isem->value = v + (1 << SEM_VALUE_SHIFT);
|
||||
|
||||
__sparc32_atomic_do_unlock24(&isem->pad);
|
||||
|
||||
if ((v & SEM_NWAITERS_MASK) != 0)
|
||||
futex_wake (&isem->value, 1, private);
|
||||
|
||||
return 0;
|
||||
}
|
||||
versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
|
||||
@ -61,19 +87,14 @@ int
|
||||
attribute_compat_text_section
|
||||
__old_sem_post (sem_t *sem)
|
||||
{
|
||||
struct sparc_old_sem *isem = (struct sparc_old_sem *) sem;
|
||||
int nr;
|
||||
int *futex = (int *) sem;
|
||||
|
||||
if (__atomic_is_v9)
|
||||
nr = atomic_increment_val (&isem->value);
|
||||
else
|
||||
{
|
||||
__sparc32_atomic_do_lock24 (&isem->lock);
|
||||
nr = ++(isem->value);
|
||||
__sparc32_atomic_do_unlock24 (&isem->lock);
|
||||
}
|
||||
int err = lll_futex_wake (&isem->value, 1,
|
||||
isem->private ^ FUTEX_PRIVATE_FLAG);
|
||||
/* We must need to synchronize with consumers of this token, so the atomic
|
||||
increment must have release MO semantics. */
|
||||
atomic_write_barrier ();
|
||||
(void) atomic_increment_val (futex);
|
||||
/* 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);
|
||||
|
Reference in New Issue
Block a user