As I recognized some weeks earlier, the __thread keyword does not work as expected (as it shall do). Reproducible: Always Steps to Reproduce: // compile with: g++ -o tls tls.cpp -lpthread #include <stdio.h> #include <pthread.h> #define MAX_THREADS 2 static __thread int i = 1; // this initialization to 1 is not happening void *thr_func(void *) { printf("pself = %d, i = %d\n", pthread_self(), i); i = pthread_self(); printf("pself = %d, i = %d\n", pthread_self(), i); return 0; } int main() { // i = 5; // comment this out if you wanna see a SEGFAULT!!!! *argh* pthread_t thread_id[MAX_THREADS]; for(int i = 0; i < MAX_THREADS; ++i) pthread_create(&thread_id[i], 0, thr_func, 0); for(int i = 0; i < MAX_THREADS; ++i) pthread_join(thread_id[i],NULL); return 0; } Actual Results: cparpart@jupiter cparpart $ ./tls pself = 16386, i = 1084849120 pself = 32771, i = 1093237728 pself = 32771, i = 32771 pself = 16386, i = 16386 Expected Results: cparpart@jupiter cparpart $ ./tls pself = 16386, i = 1 pself = 32771, i = 1 pself = 32771, i = 32771 pself = 16386, i = 16386 glibc-2.3.2, development-sources 2.5.65 (2.5.65 is needed since gentoo-sources freezes at bootup [for any reason] but I still need epoll syscall - as promised to be in gentoo-sources)
Are you *sure* you can use __thread variables before threading has been initilised? I guess that you cannot as the TLS stack has not been setup ... From that angle the result is fine.
but it still has to be initialized by 1 (in the test case). This even has been said on the gcc mailing list I am watching on.
It works fine over here: ------------------------------------------------------------------------ azarah@nosferatu tmp $ cat tls2.cpp // compile with: g++ -o tls tls.cpp -lpthread #include <stdio.h> #include <pthread.h> #define MAX_THREADS 2 static __thread int i = 1; // this initialization to 1 is not happening void *thr_func(void *) { printf("pself = %d, i = %d\n", pthread_self(), i); i = (int)pthread_self(); printf("pself = %d, i = %d\n", pthread_self(), i); return 0; } int main() { // i = 5; // comment this out if you wanna see a SEGFAULT!!!! *argh* pthread_t thread_id[MAX_THREADS]; for(int i = 0; i < MAX_THREADS; ++i) pthread_create(&thread_id[i], 0, thr_func, 0); for(int i = 0; i < MAX_THREADS; ++i) pthread_join(thread_id[i],NULL); return 0; } azarah@nosferatu tmp $ g++ -o tls2 tls2.cpp -pthread azarah@nosferatu tmp $ ./tls2 pself = 1082207552, i = 1 pself = 1082207552, i = 1082207552 pself = 1090596160, i = 1 pself = 1090596160, i = 1090596160 azarah@nosferatu tmp $ ------------------------------------------------------------------------ It even works with that 'i = 5;' uncommented: ------------------------------------------------------------------------ azarah@nosferatu tmp $ cat tls3.cpp // compile with: g++ -o tls tls.cpp -lpthread #include <stdio.h> #include <pthread.h> #define MAX_THREADS 2 static __thread int i = 1; // this initialization to 1 is not happening void *thr_func(void *) { printf("pself = %d, i = %d\n", pthread_self(), i); i = (int)pthread_self(); printf("pself = %d, i = %d\n", pthread_self(), i); return 0; } int main() { i = 5; // comment this out if you wanna see a SEGFAULT!!!! *argh* pthread_t thread_id[MAX_THREADS]; for(int i = 0; i < MAX_THREADS; ++i) pthread_create(&thread_id[i], 0, thr_func, 0); for(int i = 0; i < MAX_THREADS; ++i) pthread_join(thread_id[i],NULL); return 0; } azarah@nosferatu tmp $ g++ -o tls3 tls3.cpp -pthread azarah@nosferatu tmp $ ./tls3 pself = 1082207552, i = 1 pself = 1082207552, i = 1082207552 pself = 1090596160, i = 1 pself = 1090596160, i = 1090596160 azarah@nosferatu tmp $ ------------------------------------------------------------------------ What version of gcc ?
Oh, and you know that glibc-2.3.2 only gets compiled with '--with-tls' and '--with-__thread' if you add 'nptl' to your USE flags ?
Can we close this ?
hold on, I'm going to do some tests tonight
And?
Well, sorry, I've been busy for some time. First, I'm using gcc 3.2.2-r2, and glibc 2.3.2. I last updated gcc (3.2.2-r1) and doing actually an update to 3.2.2-r3. Then I'll (just to be sure) remerge glibc again and check this out....... Well, okay, I just can't update gcc to 3.2.2-r3 (WTF?).... So I my next step is to remerge glibc 3.2.2, AND I recognized - while reading the ebuild before - that you only get __thread support when you use nptl - which I unfortuantely can't use since I need nvidia-glx. I modified the ebuild as below: +318 myconf="${myconf} --with-tls --with-__thread \ -318 myconf="${myconf} --without-tls --without-__thread \ and am now trying it agian :( (p.s.: doesn't the old linuxthreads work with-tls and with-__thread?) Okay, while it is compiling, I'll submit this and will notify you about a success or so. If it works, I HIGHLY suggest to enable tls and __thread support by default. Greets, Christian Parpart..........
jupiter cparpart # g++ -o tls tls.cpp -lpthread -pthread jupiter cparpart # ./tls pself = 16386, i = 1 pself = 16386, i = 16386 pself = 32771, i = 1 pself = 32771, i = 32771 Okay, works as excpeted now. However, I had to patch the ebuild which can't be the excpeted way for an average user. So, I propose to enable TLS (and __thread) by default(!) since NPTL is'nt the only one depending on it. If _this_ is done, we can close this bug (as fixed ;) Cheers, Christian Parpart.
No. If your kernel/compiler do not support it 100%, then if you even get glibc to compile, things start to break afterwards. Until things get at such an stage that its working reliable and current gcc/kernel do not need patches to support, sure. I support what I know is working 100% (most of the time anyhow), and in such environment, that whoever have that configuration 'should' know what they are doing, and expect problems might occur for using that setup.
Wont fix.