diff options
-rw-r--r-- | README.google | 17 | ||||
-rw-r--r-- | nptl/Versions | 1 | ||||
-rw-r--r-- | nptl/pthread_key_create.c | 57 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/pthread.h | 14 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/bits/local_lim.h | 1 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h | 1 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h | 1 | ||||
-rw-r--r-- | nptl/tst-key1.c | 4 | ||||
-rw-r--r-- | nptl/tst-key4.c | 4 | ||||
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/aarch64/nptl/bits/local_lim.h | 1 | ||||
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/alpha/nptl/bits/local_lim.h | 1 | ||||
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/mips/nptl/bits/local_lim.h | 1 | ||||
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/tile/bits/local_lim.h | 1 |
13 files changed, 86 insertions, 18 deletions
diff --git a/README.google b/README.google index da61b373ef..e817c6b277 100644 --- a/README.google +++ b/README.google @@ -245,3 +245,20 @@ sysdeps/generic/ldsodefs.h For b/4074041, add EXEC_ORIGIN support. Forward-ported from cl/56955623 and cl/59961863. (bmoses, google-local) + +nptl/Versions +nptl/pthread_key_create.c +nptl/sysdeps/pthread/pthread.h +nptl/sysdeps/unix/sysv/linux/bits/local_lim.h +nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h +nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h +nptl/tst-key1.c +nptl/tst-key4.c +ports/sysdeps/unix/sysv/linux/aarch64/nptl/bits/local_lim.h +ports/sysdeps/unix/sysv/linux/alpha/nptl/bits/local_lim.h +ports/sysdeps/unix/sysv/linux/mips/nptl/bits/local_lim.h +ports/sysdeps/unix/sysv/linux/tile/bits/local_lim.h + Add pthread_signal_safe_key_create. + Forward ported from cl/59612021, cl/59817832, and cl/59176280. + (ahh, google-local) + diff --git a/nptl/Versions b/nptl/Versions index bb1127701e..1610909080 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -258,6 +258,7 @@ libpthread { } GLIBC_PRIVATE { + __google_pthread_signal_safe_key_create; __pthread_initialize_minimal; __pthread_clock_gettime; __pthread_clock_settime; __pthread_unwind; __pthread_get_minstack; diff --git a/nptl/pthread_key_create.c b/nptl/pthread_key_create.c index a22e446e18..49ad5d6fa9 100644 --- a/nptl/pthread_key_create.c +++ b/nptl/pthread_key_create.c @@ -18,33 +18,54 @@ #include <errno.h> #include "pthreadP.h" +#include <assert.h> #include <atomic.h> +static int +claim_key (pthread_key_t *key, void (*destr) (void *), size_t cnt) +{ + uintptr_t seq = __pthread_keys[cnt].seq; + if (KEY_UNUSED (seq) && KEY_USABLE (seq) + /* We found an unused slot. Try to allocate it. */ + && ! atomic_compare_and_exchange_bool_acq (&__pthread_keys[cnt].seq, + seq + 1, seq)) + { + /* Remember the destructor. */ + __pthread_keys[cnt].destr = destr; + + /* Return the key to the caller. */ + *key = cnt; + return 0; + } + return -1; +} int __pthread_key_create (key, destr) pthread_key_t *key; void (*destr) (void *); { - /* Find a slot in __pthread_kyes which is unused. */ - for (size_t cnt = 0; cnt < PTHREAD_KEYS_MAX; ++cnt) + /* Find a slot in __pthread_keys which is unused. */ + for (size_t cnt = PTHREAD_SIGNAL_SAFE_KEYS_MAX; cnt < PTHREAD_KEYS_MAX; ++cnt) + { + if (claim_key (key, destr, cnt) == 0) + return 0; + } + + return EAGAIN; +} + +int __google_pthread_signal_safe_key_create ( + pthread_key_t *key, void (*destr) (void *)) +{ + /* Our implementation makes signal safe keys easy: they just have to + reside in the first (inline) block. */ + assert (PTHREAD_SIGNAL_SAFE_KEYS_MAX <= PTHREAD_KEY_1STLEVEL_SIZE); + /* Find a slot in __pthread_keys which is unused. */ + for (size_t cnt = 0; cnt < PTHREAD_SIGNAL_SAFE_KEYS_MAX; ++cnt) { - uintptr_t seq = __pthread_keys[cnt].seq; - - if (KEY_UNUSED (seq) && KEY_USABLE (seq) - /* We found an unused slot. Try to allocate it. */ - && ! atomic_compare_and_exchange_bool_acq (&__pthread_keys[cnt].seq, - seq + 1, seq)) - { - /* Remember the destructor. */ - __pthread_keys[cnt].destr = destr; - - /* Return the key to the caller. */ - *key = cnt; - - /* The call succeeded. */ - return 0; - } + if (claim_key (key, destr, cnt) == 0) + return 0; } return EAGAIN; diff --git a/nptl/sysdeps/pthread/pthread.h b/nptl/sysdeps/pthread/pthread.h index 1e0c5dc937..3888596a74 100644 --- a/nptl/sysdeps/pthread/pthread.h +++ b/nptl/sysdeps/pthread/pthread.h @@ -1123,6 +1123,20 @@ extern int pthread_key_create (pthread_key_t *__key, void (*__destr_function) (void *)) __THROW __nonnull ((1)); +/* Exactly as pthread_key_create, but returns an async-signal-safe key: + getspecific, setspecific, and key_delete are async-signal-safe when + used with the returned key. The number of signal_safe keys is *extremely* + limited (PTHREAD_SIGNAL_SAFE_KEY_MAX); you are highly recommended to use + pthread_key_create unless it's absolutely necessary. This function + is async-signal-safe. */ +#if !defined(IS_IN_libpthread) +__attribute__((weak)) +#endif +extern int __google_pthread_signal_safe_key_create (pthread_key_t *__key, + void (*__destr_function) (void *)) + __THROW __nonnull ((1)); + + /* Destroy KEY. */ extern int pthread_key_delete (pthread_key_t __key) __THROW; diff --git a/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h index b802facd5d..13f2586a32 100644 --- a/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h +++ b/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h @@ -62,6 +62,7 @@ #define _POSIX_THREAD_KEYS_MAX 128 /* This is the value this implementation supports. */ #define PTHREAD_KEYS_MAX 1024 +#define PTHREAD_SIGNAL_SAFE_KEYS_MAX 4 /* Controlling the iterations of destructors for thread-specific data. */ #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h index e022226a5b..570dd223fa 100644 --- a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h +++ b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/local_lim.h @@ -62,6 +62,7 @@ #define _POSIX_THREAD_KEYS_MAX 128 /* This is the value this implementation supports. */ #define PTHREAD_KEYS_MAX 1024 +#define PTHREAD_SIGNAL_SAFE_KEYS_MAX 4 /* Controlling the iterations of destructors for thread-specific data. */ #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h b/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h index ad68f5060f..176025352b 100644 --- a/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h +++ b/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h @@ -62,6 +62,7 @@ #define _POSIX_THREAD_KEYS_MAX 128 /* This is the value this implementation supports. */ #define PTHREAD_KEYS_MAX 1024 +#define PTHREAD_SIGNAL_SAFE_KEYS_MAX 4 /* Controlling the iterations of destructors for thread-specific data. */ #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 diff --git a/nptl/tst-key1.c b/nptl/tst-key1.c index b40fffc33b..af5cb7e5cc 100644 --- a/nptl/tst-key1.c +++ b/nptl/tst-key1.c @@ -28,7 +28,11 @@ do_test (void) { int max; #ifdef PTHREAD_KEYS_MAX +#ifdef PTHREAD_SIGNAL_SAFE_KEYS_MAX + max = PTHREAD_KEYS_MAX - PTHREAD_SIGNAL_SAFE_KEYS_MAX; +#else max = PTHREAD_KEYS_MAX; +#endif #else max = _POSIX_THREAD_KEYS_MAX; #endif diff --git a/nptl/tst-key4.c b/nptl/tst-key4.c index 9e65b59cae..d431c36366 100644 --- a/nptl/tst-key4.c +++ b/nptl/tst-key4.c @@ -24,7 +24,11 @@ #ifdef PTHREAD_KEYS_MAX +#ifdef PTHREAD_SIGNAL_SAFE_KEYS_MAX +const int max = PTHREAD_KEYS_MAX - PTHREAD_SIGNAL_SAFE_KEYS_MAX; +#else const int max = PTHREAD_KEYS_MAX; +#endif #else const int max = _POSIX_THREAD_KEYS_MAX; #endif diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/bits/local_lim.h b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/bits/local_lim.h index 0b01c72de4..10f27b9ec2 100644 --- a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/bits/local_lim.h +++ b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/bits/local_lim.h @@ -63,6 +63,7 @@ #define _POSIX_THREAD_KEYS_MAX 128 /* This is the value this implementation supports. */ #define PTHREAD_KEYS_MAX 1024 +#define PTHREAD_SIGNAL_SAFE_KEYS_MAX 4 /* Controlling the iterations of destructors for thread-specific data. */ #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 diff --git a/ports/sysdeps/unix/sysv/linux/alpha/nptl/bits/local_lim.h b/ports/sysdeps/unix/sysv/linux/alpha/nptl/bits/local_lim.h index 950273e063..70e8665b0a 100644 --- a/ports/sysdeps/unix/sysv/linux/alpha/nptl/bits/local_lim.h +++ b/ports/sysdeps/unix/sysv/linux/alpha/nptl/bits/local_lim.h @@ -62,6 +62,7 @@ #define _POSIX_THREAD_KEYS_MAX 128 /* This is the value this implementation supports. */ #define PTHREAD_KEYS_MAX 1024 +#define PTHREAD_SIGNAL_SAFE_KEYS_MAX 4 /* Controlling the iterations of destructors for thread-specific data. */ #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 diff --git a/ports/sysdeps/unix/sysv/linux/mips/nptl/bits/local_lim.h b/ports/sysdeps/unix/sysv/linux/mips/nptl/bits/local_lim.h index 2366908d9c..32a6775f38 100644 --- a/ports/sysdeps/unix/sysv/linux/mips/nptl/bits/local_lim.h +++ b/ports/sysdeps/unix/sysv/linux/mips/nptl/bits/local_lim.h @@ -62,6 +62,7 @@ #define _POSIX_THREAD_KEYS_MAX 128 /* This is the value this implementation supports. */ #define PTHREAD_KEYS_MAX 1024 +#define PTHREAD_SIGNAL_SAFE_KEYS_MAX 4 /* Controlling the iterations of destructors for thread-specific data. */ #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 diff --git a/ports/sysdeps/unix/sysv/linux/tile/bits/local_lim.h b/ports/sysdeps/unix/sysv/linux/tile/bits/local_lim.h index 4e5605fd52..2f92153d93 100644 --- a/ports/sysdeps/unix/sysv/linux/tile/bits/local_lim.h +++ b/ports/sysdeps/unix/sysv/linux/tile/bits/local_lim.h @@ -62,6 +62,7 @@ #define _POSIX_THREAD_KEYS_MAX 128 /* This is the value this implementation supports. */ #define PTHREAD_KEYS_MAX 1024 +#define PTHREAD_SIGNAL_SAFE_KEYS_MAX 4 /* Controlling the iterations of destructors for thread-specific data. */ #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 |