I am trying to use __thread in this small program without luck. Any idea if this TLS is supported in ndk 10c clang 3.4/3.5? The same program compiles fine with ndk gcc 4.8/4.9 and native clang/gcc compilers.
Here is the program and compile line -
__thread int counter;
int main () { counter=20; return 0; }
[armeabi] Compile++ thumb: test <= test.cpp
/Users/padlar/android/android-ndk-r10c/toolchains/llvm-3.5/prebuilt/darwin-x86/bin/clang++ -MMD -MP -MF ./obj/local/armeabi/objs/test/test.o.d -gcc-toolchain /Users/padlar/android/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86 -fpic -ffunction-sections -funwind-tables -fstack-protector -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -fno-integrated-as -target armv5te-none-linux-androideabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -fno-rtti -mthumb -Os -g -DNDEBUG -fomit-frame-pointer -fno-strict-aliasing -I/Users/padlar/android/android-ndk-r10c/sources/cxx-stl/stlport/stlport -I/Users/padlar/android/android-ndk-r10c/sources/cxx-stl//gabi++/include -Ijni -DANDROID -Wa,--noexecstack -Wformat -Werror=format-security -fPIE -frtti -I/Users/padlar/android/android-ndk-r10c/platforms/android-19/arch-arm/usr/include -c jni/test.cpp -o ./obj/local/armeabi/objs/test/test.o
[armeabi] Executable : test
/Users/padlar/android/android-ndk-r10c/toolchains/llvm-3.5/prebuilt/darwin-x86/bin/clang++ -Wl,--gc-sections -Wl,-z,nocopyreloc --sysroot=/Users/padlar/android/android-ndk-r10c/platforms/android-19/arch-arm -Wl,-rpath-link=/Users/padlar/android/android-ndk-r10c/platforms/android-19/arch-arm/usr/lib -Wl,-rpath-link=./obj/local/armeabi ./obj/local/armeabi/objs/test/test.o /Users/padlar/android/android-ndk-r10c/sources/cxx-stl/stlport/libs/armeabi/thumb/libstlport_static.a -lgcc -gcc-toolchain /Users/padlar/android/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86 -no-canonical-prefixes -target armv5te-none-linux-androideabi -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -fPIE -pie -L/Users/padlar/android/android-ndk-r10c/platforms/android-19/arch-arm/usr/lib -llog -lc -lm -o ./obj/local/armeabi/test
jni/test.cpp:2: error: undefined reference to '__aeabi_read_tp'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [obj/local/armeabi/test] Error 1
ndk-which objdump
-S obj/local/armeabi/objs/test/test.o
obj/local/armeabi/objs/test/test.o: file format elf32-littlearm
Disassembly of section .text.main:
00000000 <main>:
__thread int counter;
int main () { counter=20; return 0; }
0: b580 push {r7, lr}
2: 4904 ldr r1, [pc, #16] ; (14 <main+0x14>)
4: f7ff fffe bl 0 <__aeabi_read_tp>
8: 1840 adds r0, r0, r1
a: 2114 movs r1, #20
c: 6001 str r1, [r0, #0]
e: 2000 movs r0, #0
10: bd80 pop {r7, pc}
12: 46c0 nop ; (mov r8, r8)
14: 00000000 .word 0x00000000
gcc4.6 disass of the same program
ndk-which objdump
-S obj/local/armeabi/objs/test/test.o
obj/local/armeabi/objs/test/test.o: file format elf32-littlearm
Disassembly of section .text.startup.main:
00000000 <main>:
__thread int counter;
int main () { counter=20; return 0; }
0: b508 push {r3, lr}
2: 4804 ldr r0, [pc, #16] ; (14 <main+0x14>)
4: 4478 add r0, pc
6: f7ff fffe bl 0 <__emutls_get_address>
a: 2314 movs r3, #20
c: 6003 str r3, [r0, #0]
e: 2000 movs r0, #0
10: bd08 pop {r3, pc}
12: 46c0 nop ; (mov r8, r8)
14: 0000000c .word 0x0000000c
__thread
style TLS (similarly C++11 style thread_local
) is not currently supported by the Android linker (we're working on it though). For now you'll have to use pthread_getspecific
and pthread_setspecific
.
EDIT: Starting with NDK r12, Clang has support for emulated TLS. While the above is still technically true (the linker on the device does not support this), the compiler can replace builtin TLS support with pthread calls on your behalf.
NB: Android still only supports thread_local
for objects with trivial destructors until r14. See discussions on https://github.com/android-ndk/ndk/issues/156#issuecomment-231878690 and https://github.com/android-ndk/ndk/issues/216.
Firstly, you should avoid using __thread as it may not be portable.
Here is what gnu gcc says here https://gcc.gnu.org/onlinedocs/gcc-4.8.3/gcc/Thread-Local.html :
The runtime model GCC uses to implement this originates in the IA-64 processor-specific ABI, but has since been migrated to other processors as well. It requires significant support from the linker (ld), dynamic linker (ld.so), and system libraries (libc.so and libpthread.so), so it is not available everywhere.
And from wikipédia http://en.wikipedia.org/wiki/Thread-local_storage#C.2B.2B :
C++0x introduces the thread_local keyword. Aside that, various C++ compiler implementations provide specific ways to declare thread-local variables:
Sun Studio C/C++, IBM XL C/C++, GNU C and Intel C/C++ (Linux systems) use the syntax:
__thread int number;
Visual C++, Intel C/C++ (Windows systems), Borland C++ Builder and Digital Mars C++ use the syntax:
__declspec(thread) int number;
Borland C++ Builder also supports the syntax:
int __thread number;
So it may work with thread_local
key word
User contributions licensed under CC BY-SA 3.0