]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/cgo: raise the thread-local storage slot search limit on Android
authorElias Naur <elias.naur@gmail.com>
Sat, 25 Mar 2017 11:55:40 +0000 (12:55 +0100)
committerElias Naur <elias.naur@gmail.com>
Mon, 27 Mar 2017 08:56:08 +0000 (08:56 +0000)
On Android, the thread local offset is found by looping through memory
starting at the TLS base address. The search is limited to
PTHREAD_KEYS_MAX, but issue 19472 made it clear that in some cases, the
slot is located further from the TLS base.

The limit is merely a sanity check in case our assumptions about the
thread-local storage layout are wrong, so this CL raises it to 384, which
is enough for the test case in issue 19472.

Fixes #19472

Change-Id: I89d1db3e9739d3a7fff5548ae487a7483c0a278a
Reviewed-on: https://go-review.googlesource.com/38636
Run-TryBot: Elias Naur <elias.naur@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/runtime/cgo/gcc_android_arm.c
src/runtime/cgo/gcc_android_arm64.c

index c7b13f9a7f4dde6b4be9f4657ca7c970b070ebfc..d8936ea00715302a477edf0fe9223b880b62f5e1 100644 (file)
 
 #define magic1 (0x23581321U)
 
-// PTHREAD_KEYS_MAX has been added to sys/limits.h at head in bionic:
-// https://android.googlesource.com/platform/bionic/+/master/libc/include/sys/limits.h
-// TODO(crawshaw): remove this definition when NDK r10d is required.
-#ifndef PTHREAD_KEYS_MAX
-#define PTHREAD_KEYS_MAX 128
-#endif
-
 // inittls allocates a thread-local storage slot for g.
 //
 // It finds the first available slot using pthread_key_create and uses
@@ -32,7 +25,11 @@ inittls(void **tlsg, void **tlsbase)
                fatalf("pthread_key_create failed: %d", err);
        }
        pthread_setspecific(k, (void*)magic1);
-       for (i=0; i<PTHREAD_KEYS_MAX; i++) {
+       // If thread local slots are laid out as we expect, our magic word will
+       // be located at some low offset from tlsbase. However, just in case something went
+       // wrong, the search is limited to sensible offsets. PTHREAD_KEYS_MAX was the
+       // original limit, but issue 19472 made a higher limit necessary.
+       for (i=0; i<384; i++) {
                if (*(tlsbase+i) == (void*)magic1) {
                        *tlsg = (void*)(i*sizeof(void *));
                        pthread_setspecific(k, 0);
index f8ad684de344cb8c9f24e90008f208d2defd75ec..499a11f7389928e1f59cd8f64ed53de1c80076a5 100644 (file)
@@ -25,7 +25,11 @@ inittls(void **tlsg, void **tlsbase)
                fatalf("pthread_key_create failed: %d", err);
        }
        pthread_setspecific(k, (void*)magic1);
-       for (i=0; i<PTHREAD_KEYS_MAX; i++) {
+       // If thread local slots are laid out as we expect, our magic word will
+       // be located at some low offset from tlsbase. However, just in case something went
+       // wrong, the search is limited to sensible offsets. PTHREAD_KEYS_MAX was the
+       // original limit, but issue 19472 made a higher limit necessary.
+       for (i=0; i<384; i++) {
                if (*(tlsbase+i) == (void*)magic1) {
                        *tlsg = (void*)(i*sizeof(void *));
                        pthread_setspecific(k, 0);