summaryrefslogtreecommitdiff
path: root/0006-add-elsion-function-which-moved-to-libc-in-glibc-2.34.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-03 06:28:41 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-03 06:28:41 +0000
commitd20db0561a6a36f914fde030512503b114ef9a0c (patch)
treed4e5e3494d95c269a1cee6195f11bf3201bcadbf /0006-add-elsion-function-which-moved-to-libc-in-glibc-2.34.patch
parent016343d99b1b269d7246ef1e143d4b54914433d4 (diff)
Diffstat (limited to '0006-add-elsion-function-which-moved-to-libc-in-glibc-2.34.patch')
-rw-r--r--0006-add-elsion-function-which-moved-to-libc-in-glibc-2.34.patch587
1 files changed, 587 insertions, 0 deletions
diff --git a/0006-add-elsion-function-which-moved-to-libc-in-glibc-2.34.patch b/0006-add-elsion-function-which-moved-to-libc-in-glibc-2.34.patch
new file mode 100644
index 0000000..e60fc08
--- /dev/null
+++ b/0006-add-elsion-function-which-moved-to-libc-in-glibc-2.34.patch
@@ -0,0 +1,587 @@
+From 1cdbe579482c07e9f4bb3baa4864da2d3e7eb837 Mon Sep 17 00:00:00 2001
+From: Andi Kleen <ak@linux.intel.com>
+Date: Sat, 10 Nov 2012 00:51:26 -0800i
+Subject: [PATCH 6/9] build extra lipthreadcond so
+
+add elsion functions which moved to libc in glibc-2.34.
+Some attributes are changed and cannot be directly referenced.
+
+
+---
+ nptl_2_17/lll_timedlock_wait_2_17.c | 59 +++++++++++++++++++++++++++++
+ nptl_2_17/elision-conf_2_17.c | 138 +++++++++++++++++++++++++++++++
+ nptl_2_17/elision-lock_2_17.c | 107 ++++++++++++++++++++++++
+ nptl_2_17/elision-timed_2_17.c | 27 ++++++
+ nptl_2_17/elision-trylock_2_17.c | 75 +++++++++++++++++
+ nptl_2_17/elision-unlock_2_17.c | 34 ++++++++
+ nptl_2_17/hle_2_17.h | 75 +++++++++++++++++
+ 6 files changed, 515
+ insertions(+)
+ create mode 100644 nptl_2_17/lll_timedlock_wait_2_17.c
+ create mode 100644 nptl_2_17/elision-conf_2_17.c
+ create mode 100644 nptl_2_17/elision-lock_2_17.c
+ create mode 100644 nptl_2_17/elision-timed_2_17.c
+ create mode 100644 nptl_2_17/elision-trylock_2_17.c
+ create mode 100644 nptl_2_17/elision-unlock_2_17.c
+ create mode 100644 nptl_2_17/hle_2_17.h
+
+diff --git a/nptl_2_17/lll_timedlock_wait_2_17.c b/nptl_2_17/lll_timedlock_wait_2_17.c
+new file mode 100644
+index 00000000..91bf9637
+--- /dev/null
++++ b/nptl_2_17/lll_timedlock_wait_2_17.c
+@@ -0,0 +1,59 @@
++/* Timed low level locking for pthread library. Generic futex-using version.
++ Copyright (C) 2003-2018 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
++
++ 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 <errno.h>
++#include <lowlevellock.h>
++#include <sys/time.h>
++
++
++int
++__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
++{
++ /* Reject invalid timeouts. */
++ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
++ return EINVAL;
++
++ /* Try locking. */
++ while (atomic_exchange_acq (futex, 2) != 0)
++ {
++ struct timeval tv;
++
++ /* Get the current time. */
++ (void) __gettimeofday (&tv, NULL);
++
++ /* Compute relative timeout. */
++ struct timespec rt;
++ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
++ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
++ if (rt.tv_nsec < 0)
++ {
++ rt.tv_nsec += 1000000000;
++ --rt.tv_sec;
++ }
++
++ if (rt.tv_sec < 0)
++ return ETIMEDOUT;
++
++ /* If *futex == 2, wait until woken or timeout. */
++ lll_futex_timed_wait (futex, 2, &rt, private);
++ }
++
++ return 0;
++}
+diff --git a/nptl_2_17/elision-conf_2_17.c b/nptl_2_17/elision-conf_2_17.c
+new file mode 100644
+index 00000000..22af2944
+--- /dev/null
++++ b/nptl_2_17/elision-conf_2_17.c
+@@ -0,0 +1,138 @@
++/* elision-conf.c: Lock elision tunable parameters.
++ Copyright (C) 2013-2018 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 <init-arch.h>
++#include <elision-conf.h>
++#include <unistd.h>
++
++#if HAVE_TUNABLES
++# define TUNABLE_NAMESPACE elision
++#endif
++#include <elf/dl-tunables.h>
++
++/* Reasonable initial tuning values, may be revised in the future.
++ This is a conservative initial value. */
++
++struct elision_config __elision_aconf =
++ {
++ /* How often to not attempt to use elision if a transaction aborted
++ 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 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. */
++ .retry_try_xbegin = 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 upgraded to elision in
++ pthread_mutex_lock(). Disabled for suid programs. Only used when elision
++ is available. */
++
++int __pthread_force_elision attribute_hidden = 0;
++
++#if HAVE_TUNABLES
++static inline void
++__always_inline
++do_set_elision_enable (int32_t elision_enable)
++{
++ /* Enable elision if it's avaliable in hardware. It's not necessary to check
++ if __libc_enable_secure isn't enabled since elision_enable will be set
++ according to the default, which is disabled. */
++ if (elision_enable == 1)
++ __pthread_force_elision = HAS_CPU_FEATURE (RTM) ? 1 : 0;
++}
++
++/* The pthread->elision_enable tunable is 0 or 1 indicating that elision
++ should be disabled or enabled respectively. The feature will only be used
++ if it's supported by the hardware. */
++
++void
++TUNABLE_CALLBACK (set_elision_enable) (tunable_val_t *valp)
++{
++ int32_t elision_enable = (int32_t) valp->numval;
++ do_set_elision_enable (elision_enable);
++}
++
++#define TUNABLE_CALLBACK_FNDECL(__name, __type) \
++static inline void \
++__always_inline \
++do_set_elision_ ## __name (__type value) \
++{ \
++ __elision_aconf.__name = value; \
++} \
++void \
++TUNABLE_CALLBACK (set_elision_ ## __name) (tunable_val_t *valp) \
++{ \
++ __type value = (__type) (valp)->numval; \
++ do_set_elision_ ## __name (value); \
++}
++
++TUNABLE_CALLBACK_FNDECL (skip_lock_busy, int32_t);
++TUNABLE_CALLBACK_FNDECL (skip_lock_internal_abort, int32_t);
++TUNABLE_CALLBACK_FNDECL (retry_try_xbegin, int32_t);
++TUNABLE_CALLBACK_FNDECL (skip_trylock_internal_abort, int32_t);
++#endif
++
++/* Initialize elision. */
++
++static void
++elision_init (int argc __attribute__ ((unused)),
++ char **argv __attribute__ ((unused)),
++ char **environ)
++{
++#if HAVE_TUNABLES
++ /* Elision depends on tunables and must be explicitly turned on by setting
++ the appropriate tunable on a supported platform. */
++
++ TUNABLE_GET (enable, int32_t,
++ TUNABLE_CALLBACK (set_elision_enable));
++ TUNABLE_GET (skip_lock_busy, int32_t,
++ TUNABLE_CALLBACK (set_elision_skip_lock_busy));
++ TUNABLE_GET (skip_lock_internal_abort, int32_t,
++ TUNABLE_CALLBACK (set_elision_skip_lock_internal_abort));
++ TUNABLE_GET (tries, int32_t,
++ TUNABLE_CALLBACK (set_elision_retry_try_xbegin));
++ TUNABLE_GET (skip_trylock_internal_abort, int32_t,
++ TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort));
++#endif
++
++ if (!__pthread_force_elision)
++ __elision_aconf.retry_try_xbegin = 0; /* Disable elision on rwlocks. */
++}
++
++#ifdef SHARED
++# define INIT_SECTION ".init_array"
++#else
++# define INIT_SECTION ".preinit_array"
++#endif
++
++void (*const __pthread_init_array []) (int, char **, char **)
++ __attribute__ ((section (INIT_SECTION), aligned (sizeof (void *)))) =
++{
++ &elision_init
++};
+diff --git a/nptl_2_17/elision-lock_2_17.c b/nptl_2_17/elision-lock_2_17.c
+new file mode 100644
+index 00000000..e6dbbc21
+--- /dev/null
++++ b/nptl_2_17/elision-lock_2_17.c
+@@ -0,0 +1,107 @@
++/* elision-lock.c: Elided pthread mutex lock.
++ Copyright (C) 2011-2018 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_2_17.h>
++#include "pthreadP_2_17.h"
++#include "lowlevellock.h"
++#include "hle_2_17.h"
++#include <elision-conf.h>
++
++#if !defined(LLL_LOCK) && !defined(EXTRAARG)
++/* Make sure the configuration code is always linked in for static
++ libraries. */
++#include "elision-conf_2_17.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 *futex, short *adapt_count, EXTRAARG int private)
++{
++ /* adapt_count can be accessed concurrently; these accesses can be both
++ inside of transactions (if critical sections are nested and the outer
++ critical section uses lock elision) and outside of transactions. Thus,
++ we need to use atomic accesses to avoid data races. However, the
++ value of adapt_count is just a hint, so relaxed MO accesses are
++ sufficient. */
++ if (atomic_load_relaxed (adapt_count) <= 0)
++ {
++ unsigned status;
++ int try_xbegin;
++
++ for (try_xbegin = aconf.retry_try_xbegin;
++ try_xbegin > 0;
++ try_xbegin--)
++ {
++ if ((status = _xbegin()) == _XBEGIN_STARTED)
++ {
++ if (*futex == 0)
++ return 0;
++
++ /* Lock was busy. Fall back to normal locking.
++ Could also _xend here but xabort with 0xff code
++ is more visible in the profiler. */
++ _xabort (_ABORT_LOCK_BUSY);
++ }
++
++ if (!(status & _XABORT_RETRY))
++ {
++ if ((status & _XABORT_EXPLICIT)
++ && _XABORT_CODE (status) == _ABORT_LOCK_BUSY)
++ {
++ /* Right now we skip here. Better would be to wait a bit
++ and retry. This likely needs some spinning. See
++ above for why relaxed MO is sufficient. */
++ if (atomic_load_relaxed (adapt_count)
++ != aconf.skip_lock_busy)
++ atomic_store_relaxed (adapt_count, aconf.skip_lock_busy);
++ }
++ /* Internal abort. There is no chance for retry.
++ Use the normal locking and next time use lock.
++ Be careful to avoid writing to the lock. See above for why
++ relaxed MO is sufficient. */
++ else if (atomic_load_relaxed (adapt_count)
++ != aconf.skip_lock_internal_abort)
++ atomic_store_relaxed (adapt_count,
++ aconf.skip_lock_internal_abort);
++ break;
++ }
++ }
++ }
++ else
++ {
++ /* Use a normal lock until the threshold counter runs out.
++ Lost updates possible. */
++ atomic_store_relaxed (adapt_count,
++ atomic_load_relaxed (adapt_count) - 1);
++ }
++
++ /* Use a normal lock here. */
++ return LLL_LOCK ((*futex), private);
++}
+diff --git a/nptl_2_17/elision-timed_2_17.c b/nptl_2_17/elision-timed_2_17.c
+new file mode 100644
+index 00000000..5050f2d1
+--- /dev/null
++++ b/nptl_2_17/elision-timed_2_17.c
+@@ -0,0 +1,27 @@
++/* elision-timed.c: Lock elision timed lock.
++ Copyright (C) 2013-2018 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"
++#include <old_macros_2_17.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_2_17.c"
+diff --git a/nptl_2_17/elision-trylock_2_17.c b/nptl_2_17/elision-trylock_2_17.c
+new file mode 100644
+index 00000000..70d8f8b9
+--- /dev/null
++++ b/nptl_2_17/elision-trylock_2_17.c
+@@ -0,0 +1,75 @@
++/* elision-trylock.c: Lock eliding trylock for pthreads.
++ Copyright (C) 2013-2018 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_2_17.h>
++
++#include <lowlevellock.h>
++#include "hle_2_17.h"
++#include <elision-conf.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
++ trylock. Sorry. After the abort the code is re-executed
++ non transactional and if the lock was already locked
++ return an error. */
++ _xabort (_ABORT_NESTED_TRYLOCK);
++
++ /* Only try a transaction if it's worth it. See __lll_lock_elision for
++ why we need atomic accesses. Relaxed MO is sufficient because this is
++ just a hint. */
++ if (atomic_load_relaxed (adapt_count) <= 0)
++ {
++ unsigned status;
++
++ if ((status = _xbegin()) == _XBEGIN_STARTED)
++ {
++ if (*futex == 0)
++ return 0;
++
++ /* Lock was busy. Fall back to normal locking.
++ Could also _xend here but xabort with 0xff code
++ is more visible in the profiler. */
++ _xabort (_ABORT_LOCK_BUSY);
++ }
++
++ if (!(status & _XABORT_RETRY))
++ {
++ /* Internal abort. No chance for retry. For future
++ locks don't try speculation for some time. See above for MO. */
++ if (atomic_load_relaxed (adapt_count)
++ != aconf.skip_lock_internal_abort)
++ atomic_store_relaxed (adapt_count, aconf.skip_lock_internal_abort);
++ }
++ /* Could do some retries here. */
++ }
++ else
++ {
++ /* Lost updates are possible but harmless (see above). */
++ atomic_store_relaxed (adapt_count,
++ atomic_load_relaxed (adapt_count) - 1);
++ }
++
++ return lll_trylock (*futex);
++}
+diff --git a/nptl_2_17/elision-unlock_2_17.c b/nptl_2_17/elision-unlock_2_17.c
+new file mode 100644
+index 00000000..b5d38c5f
+--- /dev/null
++++ b/nptl_2_17/elision-unlock_2_17.c
+@@ -0,0 +1,34 @@
++/* elision-unlock.c: Commit an elided pthread lock.
++ Copyright (C) 2013-2018 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_2_17.h"
++#include "lowlevellock.h"
++#include "hle_2_17.h"
++#include <old_macros_2_17.h>
++
++int
++__lll_unlock_elision(int *lock, int private)
++{
++ /* When the lock was free we're in a transaction.
++ When you crash here you unlocked a free lock. */
++ if (*lock == 0)
++ _xend();
++ else
++ lll_unlock ((*lock), private);
++ return 0;
++}
+diff --git a/nptl_2_17/hle_2_17.h b/nptl_2_17/hle_2_17.h
+new file mode 100644
+index 00000000..4a7b9e3b
+--- /dev/null
++++ b/nptl_2_17/hle_2_17.h
+@@ -0,0 +1,75 @@
++/* Shared RTM header. Emulate TSX intrinsics for compilers and assemblers
++ that do not support the intrinsics and instructions yet. */
++#ifndef _HLE_H
++#define _HLE_H 1
++
++#ifdef __ASSEMBLER__
++
++.macro XBEGIN target
++ .byte 0xc7,0xf8
++ .long \target-1f
++1:
++.endm
++
++.macro XEND
++ .byte 0x0f,0x01,0xd5
++.endm
++
++.macro XABORT code
++ .byte 0xc6,0xf8,\code
++.endm
++
++.macro XTEST
++ .byte 0x0f,0x01,0xd6
++.endm
++
++#endif
++
++/* Official RTM intrinsics interface matching gcc/icc, 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 _XBEGIN_STARTED (~0u)
++#define _XABORT_EXPLICIT (1 << 0)
++#define _XABORT_RETRY (1 << 1)
++#define _XABORT_CONFLICT (1 << 2)
++#define _XABORT_CAPACITY (1 << 3)
++#define _XABORT_DEBUG (1 << 4)
++#define _XABORT_NESTED (1 << 5)
++#define _XABORT_CODE(x) (((x) >> 24) & 0xff)
++
++#define _ABORT_LOCK_BUSY 0xff
++#define _ABORT_LOCK_IS_LOCKED 0xfe
++#define _ABORT_NESTED_TRYLOCK 0xfd
++
++#ifndef __ASSEMBLER__
++
++#define __force_inline __attribute__((__always_inline__)) inline
++
++static __force_inline int _xbegin(void)
++{
++ int ret = _XBEGIN_STARTED;
++ asm volatile (".byte 0xc7,0xf8 ; .long 0" : "+a" (ret) :: "memory");
++ return ret;
++}
++
++static __force_inline void _xend(void)
++{
++ asm volatile (".byte 0x0f,0x01,0xd5" ::: "memory");
++}
++
++static __force_inline void _xabort(const unsigned int status)
++{
++ asm volatile (".byte 0xc6,0xf8,%P0" :: "i" (status) : "memory");
++}
++
++static __force_inline int _xtest(void)
++{
++ unsigned char out;
++ asm volatile (".byte 0x0f,0x01,0xd6 ; setnz %0" : "=r" (out) :: "memory");
++ return out;
++}
++
++#endif
++#endif
+--
+2.30.0
+