LEFT | RIGHT |
1 // Copyright 2014 The Go Authors. All rights reserved. | 1 // Copyright 2014 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include <android/log.h> | 5 #include <android/log.h> |
6 #include <pthread.h> | 6 #include <pthread.h> |
7 #include <signal.h> | 7 #include <signal.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
| 9 #include <sys/limits.h> |
9 #include "libcgo.h" | 10 #include "libcgo.h" |
10 | 11 |
11 #define magic1 (0x23581321U) | 12 #define magic1 (0x23581321U) |
12 | 13 |
13 // inittls finds the first available pthread slot and uses it as | 14 // PTHREAD_KEYS_MAX has been added to sys/limits.h at head in bionic: |
14 // the offset value for runtime.tlsg. | 15 // https://android.googlesource.com/platform/bionic/+/master/libc/include/sys/li
mits.h |
| 16 // TODO(crawshaw): remove this definition when a new NDK is released. |
| 17 #define PTHREAD_KEYS_MAX 128 |
| 18 |
| 19 // inittls allocates a thread-local storage slot for g. |
| 20 // |
| 21 // It finds the first available slot using pthread_key_create and uses |
| 22 // it as the offset value for runtime.tlsg. |
15 static void | 23 static void |
16 inittls(void **tlsg, void **tlsbase) | 24 inittls(void **tlsg, void **tlsbase) |
17 { | 25 { |
18 pthread_key_t k; | 26 pthread_key_t k; |
19 int i, err; | 27 int i, err; |
20 | 28 |
21 err = pthread_key_create(&k, nil); | 29 err = pthread_key_create(&k, nil); |
22 if(err != 0) { | 30 if(err != 0) { |
23 fprintf(stderr, "runtime/cgo: pthread_key_create failed: %d\n",
err); | 31 fprintf(stderr, "runtime/cgo: pthread_key_create failed: %d\n",
err); |
24 __android_log_print(ANDROID_LOG_FATAL, "runtime/cgo", "pthread_k
ey_create failed: %d", err); | 32 __android_log_print(ANDROID_LOG_FATAL, "runtime/cgo", "pthread_k
ey_create failed: %d", err); |
25 abort(); | 33 abort(); |
26 } | 34 } |
27 pthread_setspecific(k, (void*)magic1); | 35 pthread_setspecific(k, (void*)magic1); |
28 » for (i=0; i<50; i++) { | 36 » for (i=0; i<PTHREAD_KEYS_MAX; i++) { |
29 if (*(tlsbase+i) == (void*)magic1) { | 37 if (*(tlsbase+i) == (void*)magic1) { |
30 *tlsg = (void*)(i*sizeof(void *)); | 38 *tlsg = (void*)(i*sizeof(void *)); |
31 pthread_setspecific(k, 0); | 39 pthread_setspecific(k, 0); |
32 return; | 40 return; |
33 } | 41 } |
34 } | 42 } |
35 fprintf(stderr, "runtime/cgo: could not find pthread key\n"); | 43 fprintf(stderr, "runtime/cgo: could not find pthread key\n"); |
36 __android_log_print(ANDROID_LOG_FATAL, "runtime/cgo", "could not find pt
hread key"); | 44 __android_log_print(ANDROID_LOG_FATAL, "runtime/cgo", "could not find pt
hread key"); |
37 abort(); | 45 abort(); |
38 } | 46 } |
39 | 47 |
40 extern void (*x_cgo_inittls)(void **tlsg, void **tlsbase); | |
41 void (*x_cgo_inittls)(void **tlsg, void **tlsbase) = inittls; | 48 void (*x_cgo_inittls)(void **tlsg, void **tlsbase) = inittls; |
LEFT | RIGHT |