mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
powerpc: Add the lock elision using HTM
This patch adds support for lock elision using ISA 2.07 hardware transactional memory instructions for pthread_mutex primitives. Similar to s390 version, the for elision logic defined in 'force-elision.h' is only enabled if ENABLE_LOCK_ELISION is defined. Also, the lock elision code should be able to be built even with a compiler that does not provide HTM support with builtins. However I have noted the performance is sub-optimal due scheduling pressures.
This commit is contained in:
parent
ec4fbd4800
commit
8d2c0a593b
30
ChangeLog
30
ChangeLog
@ -1,3 +1,33 @@
|
|||||||
|
2014-01-12 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/Makefile [nptl]
|
||||||
|
(sysdep_routines): Add lock elision objects.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
|
||||||
|
[pthread_mutex_t] (__spins): Rework to add lock elision field.
|
||||||
|
[pthread_mutex_t] (__elision): Add field.
|
||||||
|
[__PTHREAD_SPINS]: Adjust to init lock elision field.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/elision-conf.c: New file: lock
|
||||||
|
elision definitions for powerpc.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/elision-lock.c: New file:
|
||||||
|
implementation of lock elision for powerpc.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/elision-timed.c: New file:
|
||||||
|
implementation of timed lock elision for powerpc.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/elision-trylock.c: New file:
|
||||||
|
implementation of trylock with lock elision for powerpc.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/elision-unlock.c: New file:
|
||||||
|
implementaion of unlock for lock elision for powerpc.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/force-elision.h: New file:
|
||||||
|
automatic enable lock elision for mutexes.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/htm.h: New file: hardware
|
||||||
|
transaction execution definitions for powerpc.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: New file: add TLE
|
||||||
|
definitions.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/pthread_mutex_cond_lock.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/pthread_mutex_lock.c: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/pthread_mutex_timedlock.c: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/pthread_mutex_trylock.c: Likewise.
|
||||||
|
* NEWS: Update.
|
||||||
|
|
||||||
2015-01-09 Roland McGrath <roland@hack.frob.com>
|
2015-01-09 Roland McGrath <roland@hack.frob.com>
|
||||||
|
|
||||||
* sysdeps/posix/shm-directory.c: Use <> rather than ""
|
* sysdeps/posix/shm-directory.c: Use <> rather than ""
|
||||||
|
7
NEWS
7
NEWS
@ -19,6 +19,13 @@ Version 2.21
|
|||||||
17745, 17746, 17747, 17748, 17775, 17777, 17780, 17781, 17782, 17791,
|
17745, 17746, 17747, 17748, 17775, 17777, 17780, 17781, 17782, 17791,
|
||||||
17793, 17796, 17797, 17806
|
17793, 17796, 17797, 17806
|
||||||
|
|
||||||
|
* Added support for TSX lock elision of pthread mutexes on powerpc32, powerpc64
|
||||||
|
and powerpc64le. This may improve lock scaling of existing programs on
|
||||||
|
HTM capable systems. The lock elision code is only enabled with
|
||||||
|
--enable-lock-elision=yes. Also, the TSX lock elision implementation for
|
||||||
|
powerpc will issue a transaction abort on every syscall to avoid side
|
||||||
|
effects being visible outside transactions.
|
||||||
|
|
||||||
* Optimized strcpy, stpcpy, strchrnul and strrchr implementations for
|
* Optimized strcpy, stpcpy, strchrnul and strrchr implementations for
|
||||||
AArch64. Contributed by ARM Ltd.
|
AArch64. Contributed by ARM Ltd.
|
||||||
|
|
||||||
|
@ -32,4 +32,6 @@ endif
|
|||||||
|
|
||||||
ifeq ($(subdir),nptl)
|
ifeq ($(subdir),nptl)
|
||||||
libpthread-routines += sysdep
|
libpthread-routines += sysdep
|
||||||
|
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
|
||||||
|
elision-trylock
|
||||||
endif
|
endif
|
||||||
|
@ -90,14 +90,23 @@ typedef union
|
|||||||
binary compatibility. */
|
binary compatibility. */
|
||||||
int __kind;
|
int __kind;
|
||||||
#if __WORDSIZE == 64
|
#if __WORDSIZE == 64
|
||||||
int __spins;
|
short __spins;
|
||||||
|
short __elision;
|
||||||
__pthread_list_t __list;
|
__pthread_list_t __list;
|
||||||
# define __PTHREAD_MUTEX_HAVE_PREV 1
|
# define __PTHREAD_MUTEX_HAVE_PREV 1
|
||||||
|
# define __PTHREAD_SPINS 0, 0
|
||||||
#else
|
#else
|
||||||
unsigned int __nusers;
|
unsigned int __nusers;
|
||||||
__extension__ union
|
__extension__ union
|
||||||
{
|
{
|
||||||
int __spins;
|
struct
|
||||||
|
{
|
||||||
|
short __espins;
|
||||||
|
short __elision;
|
||||||
|
# define __spins __elision_data.__espins
|
||||||
|
# define __elision __elision_data.__elision
|
||||||
|
# define __PTHREAD_SPINS { 0, 0 }
|
||||||
|
} __elision_data;
|
||||||
__pthread_slist_t __list;
|
__pthread_slist_t __list;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -106,9 +115,6 @@ typedef union
|
|||||||
long int __align;
|
long int __align;
|
||||||
} pthread_mutex_t;
|
} pthread_mutex_t;
|
||||||
|
|
||||||
/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
|
|
||||||
#define __PTHREAD_SPINS 0
|
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
|
char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
|
||||||
|
80
sysdeps/unix/sysv/linux/powerpc/elision-conf.c
Normal file
80
sysdeps/unix/sysv/linux/powerpc/elision-conf.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/* elision-conf.c: Lock elision tunable parameters.
|
||||||
|
Copyright (C) 2014 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 "config.h"
|
||||||
|
#include <pthreadP.h>
|
||||||
|
#include <elision-conf.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dl-procinfo.h>
|
||||||
|
|
||||||
|
/* Reasonable initial tuning values, may be revised in the future.
|
||||||
|
This is a conservative initial value. */
|
||||||
|
|
||||||
|
struct elision_config __elision_aconf =
|
||||||
|
{
|
||||||
|
/* How many times to use a non-transactional lock after a transactional
|
||||||
|
failure has occurred because the lock is already acquired. Expressed
|
||||||
|
in number of lock acquisition attempts. */
|
||||||
|
.skip_lock_busy = 3,
|
||||||
|
/* How often to not attempt to use elision if a transaction aborted due
|
||||||
|
to reasons other than other threads' memory accesses. Expressed in
|
||||||
|
number of lock acquisition attempts. */
|
||||||
|
.skip_lock_internal_abort = 3,
|
||||||
|
/* How often to not attempt to use elision if a lock used up all retries
|
||||||
|
without success. Expressed in number of lock acquisition attempts. */
|
||||||
|
.skip_lock_out_of_tbegin_retries = 3,
|
||||||
|
/* How often we retry using elision if there is chance for the transaction
|
||||||
|
to finish execution (e.g., it wasn't aborted due to the lock being
|
||||||
|
already acquired. */
|
||||||
|
.try_tbegin = 3,
|
||||||
|
/* Same as SKIP_LOCK_INTERNAL_ABORT but for trylock. */
|
||||||
|
.skip_trylock_internal_abort = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Force elision for all new locks. This is used to decide whether existing
|
||||||
|
DEFAULT locks should be automatically use elision in pthread_mutex_lock().
|
||||||
|
Disabled for suid programs. Only used when elision is available. */
|
||||||
|
|
||||||
|
int __pthread_force_elision attribute_hidden;
|
||||||
|
|
||||||
|
/* Initialize elision. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
elision_init (int argc __attribute__ ((unused)),
|
||||||
|
char **argv __attribute__ ((unused)),
|
||||||
|
char **environ)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_LOCK_ELISION
|
||||||
|
int elision_available = (GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_HTM) ? 1 : 0;
|
||||||
|
__pthread_force_elision = __libc_enable_secure ? 0 : elision_available;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
# define INIT_SECTION ".init_array"
|
||||||
|
# define MAYBE_CONST
|
||||||
|
#else
|
||||||
|
# define INIT_SECTION ".preinit_array"
|
||||||
|
# define MAYBE_CONST const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void (*MAYBE_CONST __pthread_init_array []) (int, char **, char **)
|
||||||
|
__attribute__ ((section (INIT_SECTION), aligned (sizeof (void *)))) =
|
||||||
|
{
|
||||||
|
&elision_init
|
||||||
|
};
|
42
sysdeps/unix/sysv/linux/powerpc/elision-conf.h
Normal file
42
sysdeps/unix/sysv/linux/powerpc/elision-conf.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* elision-conf.h: Lock elision tunable parameters.
|
||||||
|
Copyright (C) 2014 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/>. */
|
||||||
|
|
||||||
|
#ifndef _ELISION_CONF_H
|
||||||
|
#define _ELISION_CONF_H 1
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
/* Should make sure there is no false sharing on this. */
|
||||||
|
struct elision_config
|
||||||
|
{
|
||||||
|
int skip_lock_busy;
|
||||||
|
int skip_lock_internal_abort;
|
||||||
|
int skip_lock_out_of_tbegin_retries;
|
||||||
|
int try_tbegin;
|
||||||
|
int skip_trylock_internal_abort;
|
||||||
|
} __attribute__ ((__aligned__ (128)));
|
||||||
|
|
||||||
|
extern struct elision_config __elision_aconf attribute_hidden;
|
||||||
|
|
||||||
|
extern int __pthread_force_elision attribute_hidden;
|
||||||
|
|
||||||
|
/* Tell the test suite to test elision for this architecture. */
|
||||||
|
#define HAVE_ELISION 1
|
||||||
|
|
||||||
|
#endif
|
107
sysdeps/unix/sysv/linux/powerpc/elision-lock.c
Normal file
107
sysdeps/unix/sysv/linux/powerpc/elision-lock.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/* elision-lock.c: Elided pthread mutex lock.
|
||||||
|
Copyright (C) 2014 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 <stdio.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <pthreadP.h>
|
||||||
|
#include <lowlevellock.h>
|
||||||
|
#include <elision-conf.h>
|
||||||
|
#include "htm.h"
|
||||||
|
|
||||||
|
/* PowerISA 2.0.7 Section B.5.5 defines isync to be insufficient as a
|
||||||
|
barrier in acquire mechanism for HTM operations, a strong 'sync' is
|
||||||
|
required. */
|
||||||
|
#undef __arch_compare_and_exchange_val_32_acq
|
||||||
|
#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
|
||||||
|
({ \
|
||||||
|
__typeof (*(mem)) __tmp; \
|
||||||
|
__typeof (mem) __memp = (mem); \
|
||||||
|
__asm __volatile ( \
|
||||||
|
"1: lwarx %0,0,%1" MUTEX_HINT_ACQ "\n" \
|
||||||
|
" cmpw %0,%2\n" \
|
||||||
|
" bne 2f\n" \
|
||||||
|
" stwcx. %3,0,%1\n" \
|
||||||
|
" bne- 1b\n" \
|
||||||
|
"2: sync" \
|
||||||
|
: "=&r" (__tmp) \
|
||||||
|
: "b" (__memp), "r" (oldval), "r" (newval) \
|
||||||
|
: "cr0", "memory"); \
|
||||||
|
__tmp; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#if !defined(LLL_LOCK) && !defined(EXTRAARG)
|
||||||
|
/* Make sure the configuration code is always linked in for static
|
||||||
|
libraries. */
|
||||||
|
#include "elision-conf.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EXTRAARG
|
||||||
|
# define EXTRAARG
|
||||||
|
#endif
|
||||||
|
#ifndef LLL_LOCK
|
||||||
|
# define LLL_LOCK(a,b) lll_lock(a,b), 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define aconf __elision_aconf
|
||||||
|
|
||||||
|
/* Adaptive lock using transactions.
|
||||||
|
By default the lock region is run as a transaction, and when it
|
||||||
|
aborts or the lock is busy the lock adapts itself. */
|
||||||
|
|
||||||
|
int
|
||||||
|
__lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
|
||||||
|
{
|
||||||
|
if (*adapt_count > 0)
|
||||||
|
{
|
||||||
|
(*adapt_count)--;
|
||||||
|
goto use_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
int try_begin = aconf.try_tbegin;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (__builtin_tbegin (0))
|
||||||
|
{
|
||||||
|
if (*lock == 0)
|
||||||
|
return 0;
|
||||||
|
/* Lock was busy. Fall back to normal locking. */
|
||||||
|
__builtin_tabort (_ABORT_LOCK_BUSY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* A persistent failure indicates that a retry will probably
|
||||||
|
result in another failure. Use normal locking now and
|
||||||
|
for the next couple of calls. */
|
||||||
|
if (try_begin-- <= 0
|
||||||
|
|| _TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
|
||||||
|
{
|
||||||
|
if (aconf.skip_lock_internal_abort > 0)
|
||||||
|
*adapt_count = aconf.skip_lock_internal_abort;
|
||||||
|
goto use_lock;
|
||||||
|
}
|
||||||
|
/* Same logic as above, but for for a number of temporary failures
|
||||||
|
in a row. */
|
||||||
|
else if (aconf.skip_lock_out_of_tbegin_retries > 0
|
||||||
|
&& aconf.try_tbegin > 0)
|
||||||
|
*adapt_count = aconf.skip_lock_out_of_tbegin_retries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use_lock:
|
||||||
|
return LLL_LOCK ((*lock), pshared);
|
||||||
|
}
|
28
sysdeps/unix/sysv/linux/powerpc/elision-timed.c
Normal file
28
sysdeps/unix/sysv/linux/powerpc/elision-timed.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* elision-timed.c: Lock elision timed lock.
|
||||||
|
Copyright (C) 2014 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 <time.h>
|
||||||
|
#include <elision-conf.h>
|
||||||
|
#include "lowlevellock.h"
|
||||||
|
|
||||||
|
#define __lll_lock_elision __lll_timedlock_elision
|
||||||
|
#define EXTRAARG const struct timespec *t,
|
||||||
|
#undef LLL_LOCK
|
||||||
|
#define LLL_LOCK(a, b) lll_timedlock(a, t, b)
|
||||||
|
|
||||||
|
#include "elision-lock.c"
|
68
sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
Normal file
68
sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* elision-trylock.c: Lock eliding trylock for pthreads.
|
||||||
|
Copyright (C) 2014 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 <pthread.h>
|
||||||
|
#include <pthreadP.h>
|
||||||
|
#include <lowlevellock.h>
|
||||||
|
#include <elision-conf.h>
|
||||||
|
#include "htm.h"
|
||||||
|
|
||||||
|
#define aconf __elision_aconf
|
||||||
|
|
||||||
|
/* Try to elide a futex trylock. FUTEX is the futex variable. ADAPT_COUNT is
|
||||||
|
the adaptation counter in the mutex. */
|
||||||
|
|
||||||
|
int
|
||||||
|
__lll_trylock_elision (int *futex, short *adapt_count)
|
||||||
|
{
|
||||||
|
/* Implement POSIX semantics by forbiding nesting elided trylocks. */
|
||||||
|
__builtin_tabort (_ABORT_NESTED_TRYLOCK);
|
||||||
|
|
||||||
|
/* Only try a transaction if it's worth it. */
|
||||||
|
if (*adapt_count > 0)
|
||||||
|
{
|
||||||
|
(*adapt_count)--;
|
||||||
|
goto use_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__builtin_tbegin (0))
|
||||||
|
{
|
||||||
|
if (*futex == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Lock was busy. Fall back to normal locking. */
|
||||||
|
__builtin_tabort (_ABORT_LOCK_BUSY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
|
||||||
|
{
|
||||||
|
/* A persistent failure indicates that a retry will probably
|
||||||
|
result in another failure. Use normal locking now and
|
||||||
|
for the next couple of calls. */
|
||||||
|
if (aconf.skip_trylock_internal_abort > 0)
|
||||||
|
*adapt_count = aconf.skip_trylock_internal_abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aconf.skip_lock_busy > 0)
|
||||||
|
*adapt_count = aconf.skip_lock_busy;
|
||||||
|
}
|
||||||
|
|
||||||
|
use_lock:
|
||||||
|
return lll_trylock (*futex);
|
||||||
|
}
|
32
sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
Normal file
32
sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* elision-unlock.c: Commit an elided pthread lock.
|
||||||
|
Copyright (C) 2014 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 "pthreadP.h"
|
||||||
|
#include "lowlevellock.h"
|
||||||
|
#include "htm.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
__lll_unlock_elision(int *lock, int pshared)
|
||||||
|
{
|
||||||
|
/* When the lock was free we're in a transaction. */
|
||||||
|
if (*lock == 0)
|
||||||
|
__builtin_tend (0);
|
||||||
|
else
|
||||||
|
lll_unlock ((*lock), pshared);
|
||||||
|
return 0;
|
||||||
|
}
|
28
sysdeps/unix/sysv/linux/powerpc/force-elision.h
Normal file
28
sysdeps/unix/sysv/linux/powerpc/force-elision.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* force-elision.h: Automatic enabling of elision for mutexes
|
||||||
|
Copyright (C) 2014 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/>. */
|
||||||
|
|
||||||
|
#ifdef ENABLE_LOCK_ELISION
|
||||||
|
/* Automatically enable elision for existing user lock kinds. */
|
||||||
|
#define FORCE_ELISION(m, s) \
|
||||||
|
if (__pthread_force_elision \
|
||||||
|
&& (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
|
||||||
|
{ \
|
||||||
|
mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
|
||||||
|
s; \
|
||||||
|
}
|
||||||
|
#endif
|
138
sysdeps/unix/sysv/linux/powerpc/htm.h
Normal file
138
sysdeps/unix/sysv/linux/powerpc/htm.h
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/* Shared HTM header. Emulate transactional execution facility intrinsics for
|
||||||
|
compilers and assemblers that do not support the intrinsics and instructions
|
||||||
|
yet.
|
||||||
|
|
||||||
|
Copyright (C) 2014 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/>. */
|
||||||
|
|
||||||
|
#ifndef _HTM_H
|
||||||
|
#define _HTM_H 1
|
||||||
|
|
||||||
|
#ifdef __ASSEMBLER__
|
||||||
|
|
||||||
|
/* tbegin. */
|
||||||
|
.macro TBEGIN
|
||||||
|
.long 0x7c00051d
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/* tend. 0 */
|
||||||
|
.macro TEND
|
||||||
|
.long 0x7c00055d
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/* tabort. code */
|
||||||
|
.macro TABORT code
|
||||||
|
.byte 0x7c
|
||||||
|
.byte \code
|
||||||
|
.byte 0x07
|
||||||
|
.byte 0x1d
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*"TEXASR - Transaction EXception And Summary Register"
|
||||||
|
mfspr %dst,130 */
|
||||||
|
.macro TEXASR dst
|
||||||
|
mfspr \dst,130
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <endian.h>
|
||||||
|
|
||||||
|
/* Official HTM intrinsics interface matching GCC, but works
|
||||||
|
on older GCC compatible compilers and binutils.
|
||||||
|
We should somehow detect if the compiler supports it, because
|
||||||
|
it may be able to generate slightly better code. */
|
||||||
|
|
||||||
|
#define TBEGIN ".long 0x7c00051d"
|
||||||
|
#define TEND ".long 0x7c00055d"
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
# define TABORT ".byte 0x1d,0x07,%1,0x1d"
|
||||||
|
#else
|
||||||
|
# define TABORT ".byte 0x7c,%1,0x07,0x1d"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __force_inline inline __attribute__((__always_inline__))
|
||||||
|
|
||||||
|
#ifndef __HTM__
|
||||||
|
|
||||||
|
#define _TEXASRU_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \
|
||||||
|
(((TEXASR) >> (31-(BITNUM))) & ((1<<(SIZE))-1))
|
||||||
|
#define _TEXASRU_FAILURE_PERSISTENT(TEXASRU) \
|
||||||
|
_TEXASRU_EXTRACT_BITS(TEXASRU, 7, 1)
|
||||||
|
|
||||||
|
#define _tbegin() \
|
||||||
|
({ unsigned int __ret; \
|
||||||
|
asm volatile ( \
|
||||||
|
TBEGIN "\t\n" \
|
||||||
|
"mfcr %0\t\n" \
|
||||||
|
"rlwinm %0,%0,3,1\t\n" \
|
||||||
|
"xori %0,%0,1\t\n" \
|
||||||
|
: "=r" (__ret) : \
|
||||||
|
: "cr0", "memory"); \
|
||||||
|
__ret; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define _tend() \
|
||||||
|
({ unsigned int __ret; \
|
||||||
|
asm volatile ( \
|
||||||
|
TEND "\t\n" \
|
||||||
|
"mfcr %0\t\n" \
|
||||||
|
"rlwinm %0,%0,3,1\t\n" \
|
||||||
|
"xori %0,%0,1\t\n" \
|
||||||
|
: "=r" (__ret) : \
|
||||||
|
: "cr0", "memory"); \
|
||||||
|
__ret; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define _tabort(__code) \
|
||||||
|
({ unsigned int __ret; \
|
||||||
|
asm volatile ( \
|
||||||
|
TABORT "\t\n" \
|
||||||
|
"mfcr %0\t\n" \
|
||||||
|
"rlwinm %0,%0,3,1\t\n" \
|
||||||
|
"xori %0,%0,1\t\n" \
|
||||||
|
: "=r" (__ret) : "r" (__code) \
|
||||||
|
: "cr0", "memory"); \
|
||||||
|
__ret; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define _texasru() \
|
||||||
|
({ unsigned long __ret; \
|
||||||
|
asm volatile ( \
|
||||||
|
"mfspr %0,131\t\n" \
|
||||||
|
: "=r" (__ret)); \
|
||||||
|
__ret; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __builtin_tbegin(tdb) _tbegin ()
|
||||||
|
#define __builtin_tend(nested) _tend ()
|
||||||
|
#define __builtin_tabort(abortcode) _tabort (abortcode)
|
||||||
|
#define __builtin_get_texasru() _texasru ()
|
||||||
|
|
||||||
|
#else
|
||||||
|
# include <htmintrin.h>
|
||||||
|
#endif /* __HTM__ */
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
|
/* Definitions used for TEXASR Failure code (bits 0:6), they need to be even
|
||||||
|
because tabort. always sets the first bit. */
|
||||||
|
#define _ABORT_LOCK_BUSY 0x3f /* Lock already used. */
|
||||||
|
#define _ABORT_NESTED_TRYLOCK 0x3e /* Write operation in trylock. */
|
||||||
|
#define _ABORT_SYSCALL 0x3d /* Syscall issued. */
|
||||||
|
|
||||||
|
#endif
|
48
sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
Normal file
48
sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* PowerPC specific lock definitions.
|
||||||
|
Copyright (C) 2014 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/>. */
|
||||||
|
|
||||||
|
#ifndef _POWERPC_LOWLEVELLOCK_H
|
||||||
|
#define _POWERPC_LOWLEVELLOCK_H 1
|
||||||
|
|
||||||
|
#include <sysdeps/nptl/lowlevellock.h>
|
||||||
|
|
||||||
|
/* Transactional lock elision definitions. */
|
||||||
|
extern int __lll_timedlock_elision
|
||||||
|
(int *futex, short *adapt_count, const struct timespec *timeout, int private)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
#define lll_timedlock_elision(futex, adapt_count, timeout, private) \
|
||||||
|
__lll_timedlock_elision(&(futex), &(adapt_count), timeout, private)
|
||||||
|
|
||||||
|
extern int __lll_lock_elision (int *futex, short *adapt_count, int private)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
extern int __lll_unlock_elision(int *lock, int private)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
extern int __lll_trylock_elision(int *lock, short *adapt_count)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
#define lll_lock_elision(futex, adapt_count, private) \
|
||||||
|
__lll_lock_elision (&(futex), &(adapt_count), private)
|
||||||
|
#define lll_unlock_elision(futex, private) \
|
||||||
|
__lll_unlock_elision (&(futex), private)
|
||||||
|
#define lll_trylock_elision(futex, adapt_count) \
|
||||||
|
__lll_trylock_elision (&(futex), &(adapt_count))
|
||||||
|
|
||||||
|
#endif
|
22
sysdeps/unix/sysv/linux/powerpc/pthread_mutex_cond_lock.c
Normal file
22
sysdeps/unix/sysv/linux/powerpc/pthread_mutex_cond_lock.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* Copyright (C) 2014 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/>. */
|
||||||
|
|
||||||
|
/* The cond lock is not actually elided yet, but we still need to handle
|
||||||
|
already elided locks. */
|
||||||
|
#include <elision-conf.h>
|
||||||
|
|
||||||
|
#include <nptl/pthread_mutex_cond_lock.c>
|
22
sysdeps/unix/sysv/linux/powerpc/pthread_mutex_lock.c
Normal file
22
sysdeps/unix/sysv/linux/powerpc/pthread_mutex_lock.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* Elided version of pthread_mutex_lock.
|
||||||
|
Copyright (C) 2014 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 <elision-conf.h>
|
||||||
|
#include <force-elision.h>
|
||||||
|
|
||||||
|
#include <nptl/pthread_mutex_lock.c>
|
22
sysdeps/unix/sysv/linux/powerpc/pthread_mutex_timedlock.c
Normal file
22
sysdeps/unix/sysv/linux/powerpc/pthread_mutex_timedlock.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* Elided version of pthread_mutex_timedlock.
|
||||||
|
Copyright (C) 2014 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 <elision-conf.h>
|
||||||
|
#include <force-elision.h>
|
||||||
|
|
||||||
|
#include <nptl/pthread_mutex_timedlock.c>
|
22
sysdeps/unix/sysv/linux/powerpc/pthread_mutex_trylock.c
Normal file
22
sysdeps/unix/sysv/linux/powerpc/pthread_mutex_trylock.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* Elided version of pthread_mutex_trylock.
|
||||||
|
Copyright (C) 2014 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 <elision-conf.h>
|
||||||
|
#include <force-elision.h>
|
||||||
|
|
||||||
|
#include <nptl/pthread_mutex_trylock.c>
|
Loading…
Reference in New Issue
Block a user