mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-03 16:21:06 +00:00
Add generic versions of pthread_spin_lock and pthread_spin_trylock.
This commit is contained in:
parent
329bc01868
commit
ef4009734b
@ -1,3 +1,8 @@
|
||||
2012-08-15 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||
|
||||
* pthread_spin_lock.c: New file.
|
||||
* pthread_spin_trylock.c: New file.
|
||||
|
||||
2012-08-08 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* allocatestack.c (setxid_signal_thread) [__ASSUME_TGKILL]: Make
|
||||
|
69
nptl/pthread_spin_lock.c
Normal file
69
nptl/pthread_spin_lock.c
Normal file
@ -0,0 +1,69 @@
|
||||
/* pthread_spin_lock -- lock a spin lock. Generic version.
|
||||
Copyright (C) 2012 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, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <atomic.h>
|
||||
#include "pthreadP.h"
|
||||
|
||||
/* A machine-specific version can define SPIN_LOCK_READS_BETWEEN_CMPXCHG
|
||||
to the number of plain reads that it's optimal to spin on between uses
|
||||
of atomic_compare_and_exchange_val_acq. If spinning forever is optimal
|
||||
then use -1. If no plain reads here would ever be optimal, use 0. */
|
||||
#ifndef SPIN_LOCK_READS_BETWEEN_CMPXCHG
|
||||
# warning machine-dependent file should define SPIN_LOCK_READS_BETWEEN_CMPXCHG
|
||||
# define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
|
||||
#endif
|
||||
|
||||
int
|
||||
pthread_spin_lock (pthread_spinlock_t *lock)
|
||||
{
|
||||
/* atomic_exchange usually takes less instructions than
|
||||
atomic_compare_and_exchange. On the other hand,
|
||||
atomic_compare_and_exchange potentially generates less bus traffic
|
||||
when the lock is locked.
|
||||
We assume that the first try mostly will be successful, and we use
|
||||
atomic_exchange. For the subsequent tries we use
|
||||
atomic_compare_and_exchange. */
|
||||
if (atomic_exchange_acq (lock, 1) == 0)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
/* The lock is contended and we need to wait. Going straight back
|
||||
to cmpxchg is not a good idea on many targets as that will force
|
||||
expensive memory synchronizations among processors and penalize other
|
||||
running threads.
|
||||
On the other hand, we do want to update memory state on the local core
|
||||
once in a while to avoid spinning indefinitely until some event that
|
||||
will happen to update local memory as a side-effect. */
|
||||
if (SPIN_LOCK_READS_BETWEEN_CMPXCHG >= 0)
|
||||
{
|
||||
int wait = SPIN_LOCK_READS_BETWEEN_CMPXCHG;
|
||||
|
||||
while (*lock != 0 && wait > 0)
|
||||
--wait;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*lock != 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
while (atomic_compare_and_exchange_val_acq (lock, 1, 0) != 0);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
/* pthread_spin_trylock -- trylock a spin lock. Generic version.
|
||||
Copyright (C) 2012 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
|
||||
@ -12,7 +13,7 @@
|
||||
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, see
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
@ -22,5 +23,5 @@
|
||||
int
|
||||
pthread_spin_trylock (pthread_spinlock_t *lock)
|
||||
{
|
||||
return atomic_compare_and_exchange_val_acq (lock, 1, 0) ? EBUSY : 0;
|
||||
return atomic_exchange_acq (lock, 1) ? EBUSY : 0;
|
||||
}
|
@ -1,3 +1,8 @@
|
||||
2012-08-15 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||
|
||||
* sysdeps/arm/nptl/pthread_spin_lock.c: Use generic code.
|
||||
* sysdeps/arm/nptl/pthread_spin_trylock.c: Remove, use generic version.
|
||||
|
||||
2012-08-14 Roland McGrath <roland@hack.frob.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h: Renamed to ...
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-08-15 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||
|
||||
* sysdeps/hppa/nptl/pthread_spin_lock.c: Use generic code.
|
||||
* sysdeps/hppa/nptl/pthread_spin_trylock.c: Remove, use generic version.
|
||||
|
||||
2012-08-12 Mike Frysinger <vapier@gentoo.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/hppa/syscalls.list: Add prlimit64.
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-08-15 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||
|
||||
* sysdeps/m68k/nptl/pthread_spin_lock.c: Use generic code.
|
||||
* sysdeps/m68k/nptl/pthread_spin_trylock.c: Remove, use generic version.
|
||||
|
||||
2012-08-10 Andreas Schwab <schwab@linux-m68k.org>
|
||||
|
||||
* sysdeps/m68k/ldsodefs.h (m68k_gnu_pltenter): Remove const on
|
||||
|
@ -1,3 +1,9 @@
|
||||
2012-08-15 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||
|
||||
* sysdeps/mips/nptl/pthread_spin_lock.S: Remove, use generic version.
|
||||
* sysdeps/mips/nptl/pthread_spin_lock.c: New file.
|
||||
* sysdeps/mips/nptl/pthread_spin_trylock.S: Remove, use generic version.
|
||||
|
||||
2012-08-15 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/mips/dl-lookup.c: Update from generic version.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2008-2012 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
|
||||
@ -15,15 +15,9 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <atomic.h>
|
||||
#include "pthreadP.h"
|
||||
#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
|
||||
|
||||
int
|
||||
pthread_spin_lock (pthread_spinlock_t *lock)
|
||||
{
|
||||
while (atomic_compare_and_exchange_val_acq (lock, 1, 0) != 0)
|
||||
while (*lock != 0)
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
|
||||
it will resolve to this very file. Using "sysdeps/.." as reference to the
|
||||
top level directory does the job. */
|
||||
#include <sysdeps/../nptl/pthread_spin_lock.c>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2005-2012 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
|
||||
@ -15,23 +15,9 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <atomic.h>
|
||||
#include "pthreadP.h"
|
||||
#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
|
||||
|
||||
int
|
||||
pthread_spin_lock (pthread_spinlock_t *lock)
|
||||
{
|
||||
#if 0
|
||||
volatile unsigned int *addr = __ldcw_align (lock);
|
||||
|
||||
while (__ldcw (addr) == 0)
|
||||
while (*addr == 0) ;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
while (atomic_compare_and_exchange_val_acq(lock, 1, 0) == 1)
|
||||
while (*lock == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
|
||||
it will resolve to this very file. Using "sysdeps/.." as reference to the
|
||||
top level directory does the job. */
|
||||
#include <sysdeps/../nptl/pthread_spin_lock.c>
|
||||
|
@ -1,33 +0,0 @@
|
||||
/* Copyright (C) 2005 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, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <atomic.h>
|
||||
#include "pthreadP.h"
|
||||
|
||||
int
|
||||
pthread_spin_trylock (pthread_spinlock_t *lock)
|
||||
{
|
||||
#if 0
|
||||
volatile unsigned int *a = __ldcw_align (lock);
|
||||
|
||||
return __ldcw (a) ? 0 : EBUSY;
|
||||
#endif
|
||||
|
||||
return atomic_compare_and_exchange_val_acq(lock, 1, 0) ? EBUSY : 0;
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2010-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010.
|
||||
|
||||
@ -16,15 +16,9 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <atomic.h>
|
||||
#include "pthreadP.h"
|
||||
#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
|
||||
|
||||
int
|
||||
pthread_spin_lock (pthread_spinlock_t *lock)
|
||||
{
|
||||
while (atomic_compare_and_exchange_val_acq(lock, 1, 0) != 0)
|
||||
while (*lock != 0)
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
|
||||
it will resolve to this very file. Using "sysdeps/.." as reference to the
|
||||
top level directory does the job. */
|
||||
#include <sysdeps/../nptl/pthread_spin_lock.c>
|
||||
|
@ -1,36 +0,0 @@
|
||||
/* Copyright (C) 2005 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, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/asm.h>
|
||||
#include <sysdep.h>
|
||||
#include <sgidefs.h>
|
||||
|
||||
ENTRY (pthread_spin_lock)
|
||||
.set push
|
||||
#if _MIPS_SIM == _ABIO32
|
||||
.set mips2
|
||||
#endif
|
||||
1: ll a2, 0(a0)
|
||||
li a1, 1
|
||||
bnez a2, 1b
|
||||
sc a1, 0(a0)
|
||||
beqz a1, 1b
|
||||
MIPS_SYNC
|
||||
.set pop
|
||||
li v0, 0
|
||||
ret
|
||||
PSEUDO_END (pthread_spin_lock)
|
@ -1,6 +1,5 @@
|
||||
/* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@ -16,12 +15,9 @@
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <atomic.h>
|
||||
#include "pthreadP.h"
|
||||
#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
|
||||
|
||||
int
|
||||
pthread_spin_trylock (pthread_spinlock_t *lock)
|
||||
{
|
||||
return atomic_compare_and_exchange_val_acq(lock, 1, 0) ? EBUSY : 0;
|
||||
}
|
||||
/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
|
||||
it will resolve to this very file. Using "sysdeps/.." as reference to the
|
||||
top level directory does the job. */
|
||||
#include <sysdeps/../nptl/pthread_spin_lock.c>
|
@ -1,40 +0,0 @@
|
||||
/* Copyright (C) 2005 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, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sys/asm.h>
|
||||
#include <sysdep.h>
|
||||
#define _ERRNO_H 1
|
||||
#include <bits/errno.h>
|
||||
#include <sgidefs.h>
|
||||
|
||||
ENTRY (pthread_spin_trylock)
|
||||
.set push
|
||||
#if _MIPS_SIM == _ABIO32
|
||||
.set mips2
|
||||
#endif
|
||||
ll a2, 0(a0)
|
||||
li a1, 1
|
||||
bnez a2, 1f
|
||||
sc a1, 0(a0)
|
||||
beqz a1, 1f
|
||||
MIPS_SYNC
|
||||
.set pop
|
||||
li v0, 0
|
||||
ret
|
||||
1: li v0, EBUSY
|
||||
ret
|
||||
PSEUDO_END (pthread_spin_trylock)
|
Loading…
Reference in New Issue
Block a user