diff options
author | CoprDistGit <infra@openeuler.org> | 2024-08-03 06:28:41 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-08-03 06:28:41 +0000 |
commit | d20db0561a6a36f914fde030512503b114ef9a0c (patch) | |
tree | d4e5e3494d95c269a1cee6195f11bf3201bcadbf /0006-add-elsion-function-which-moved-to-libc-in-glibc-2.34.patch | |
parent | 016343d99b1b269d7246ef1e143d4b54914433d4 (diff) |
automatic import of glibcopeneuler22.03_LTS_SP4openeuler22.03_LTS_SP3openeuler20.03
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.patch | 587 |
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 + |