tls_threads.c revision 9848690cfe9c59a8a92d4be6e5b43c77786066ee
19848690cfe9c59a8a92d4be6e5b43c77786066eephilippe#include <config.h> 29848690cfe9c59a8a92d4be6e5b43c77786066eephilippe#include <pthread.h> 39848690cfe9c59a8a92d4be6e5b43c77786066eephilippe#include <stdio.h> 49848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 59848690cfe9c59a8a92d4be6e5b43c77786066eephilippe#ifdef HAVE_TLS 69848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 79848690cfe9c59a8a92d4be6e5b43c77786066eephilippestatic int only_touch_stackvar; 89848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 99848690cfe9c59a8a92d4be6e5b43c77786066eephilippe/* We should have no error on local and global 109848690cfe9c59a8a92d4be6e5b43c77786066eephilippe as these are both thread local variables. */ 119848690cfe9c59a8a92d4be6e5b43c77786066eephilippestatic __thread int local; 129848690cfe9c59a8a92d4be6e5b43c77786066eephilippe__thread int global; 139848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 149848690cfe9c59a8a92d4be6e5b43c77786066eephilippe/* We will wrongly share this variable indirectly through a pointer 159848690cfe9c59a8a92d4be6e5b43c77786066eephilippe We should have an error for this. */ 169848690cfe9c59a8a92d4be6e5b43c77786066eephilippestatic __thread int badly_shared_local; 179848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 189848690cfe9c59a8a92d4be6e5b43c77786066eephilippe/* ptr_to_badly_shared_local allows to have multiple threads seeing 199848690cfe9c59a8a92d4be6e5b43c77786066eephilippe the same thread local storage. This is however really bad sharing 209848690cfe9c59a8a92d4be6e5b43c77786066eephilippe as this can cause SEGV or whatever, as when the thread disappears, 219848690cfe9c59a8a92d4be6e5b43c77786066eephilippe the badly_shared_local var pointed to can also disappear. 229848690cfe9c59a8a92d4be6e5b43c77786066eephilippe By default, the regtest does not test this really bad sharing. */ 239848690cfe9c59a8a92d4be6e5b43c77786066eephilippepthread_mutex_t protect_ptr_to_badly_shared_local = PTHREAD_MUTEX_INITIALIZER; 249848690cfe9c59a8a92d4be6e5b43c77786066eephilippeint *ptr_to_badly_shared_local; 259848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 269848690cfe9c59a8a92d4be6e5b43c77786066eephilippestatic void local_false_positive(void) 279848690cfe9c59a8a92d4be6e5b43c77786066eephilippe{ 289848690cfe9c59a8a92d4be6e5b43c77786066eephilippe local = local + 1; // no error is expected 299848690cfe9c59a8a92d4be6e5b43c77786066eephilippe} 309848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 319848690cfe9c59a8a92d4be6e5b43c77786066eephilippestatic void global_false_positive(void) 329848690cfe9c59a8a92d4be6e5b43c77786066eephilippe{ 339848690cfe9c59a8a92d4be6e5b43c77786066eephilippe global = global + 1; // no error is expected 349848690cfe9c59a8a92d4be6e5b43c77786066eephilippe} 359848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 369848690cfe9c59a8a92d4be6e5b43c77786066eephilippestatic void badly_shared_local_error_expected(void) 379848690cfe9c59a8a92d4be6e5b43c77786066eephilippe{ 389848690cfe9c59a8a92d4be6e5b43c77786066eephilippe *ptr_to_badly_shared_local = *ptr_to_badly_shared_local + 1; // an error is expected 399848690cfe9c59a8a92d4be6e5b43c77786066eephilippe // This can cause a SIGSEGV. 409848690cfe9c59a8a92d4be6e5b43c77786066eephilippe} 419848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 429848690cfe9c59a8a92d4be6e5b43c77786066eephilippestatic void *level2(void *p) 439848690cfe9c59a8a92d4be6e5b43c77786066eephilippe{ 449848690cfe9c59a8a92d4be6e5b43c77786066eephilippe int stackvar = 0; 459848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 469848690cfe9c59a8a92d4be6e5b43c77786066eephilippe stackvar = stackvar + only_touch_stackvar; 479848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 489848690cfe9c59a8a92d4be6e5b43c77786066eephilippe local_false_positive(); 499848690cfe9c59a8a92d4be6e5b43c77786066eephilippe global_false_positive(); 509848690cfe9c59a8a92d4be6e5b43c77786066eephilippe if (only_touch_stackvar != 0) { 519848690cfe9c59a8a92d4be6e5b43c77786066eephilippe badly_shared_local_error_expected(); 529848690cfe9c59a8a92d4be6e5b43c77786066eephilippe } 539848690cfe9c59a8a92d4be6e5b43c77786066eephilippe return 0; 549848690cfe9c59a8a92d4be6e5b43c77786066eephilippe} 559848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 569848690cfe9c59a8a92d4be6e5b43c77786066eephilippe#define NLEVEL2 10 579848690cfe9c59a8a92d4be6e5b43c77786066eephilippestatic void *level1(void *p) 589848690cfe9c59a8a92d4be6e5b43c77786066eephilippe{ 599848690cfe9c59a8a92d4be6e5b43c77786066eephilippe pthread_t threads[NLEVEL2]; 609848690cfe9c59a8a92d4be6e5b43c77786066eephilippe int curthread = 0; 619848690cfe9c59a8a92d4be6e5b43c77786066eephilippe int i; 629848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 639848690cfe9c59a8a92d4be6e5b43c77786066eephilippe pthread_mutex_lock(&protect_ptr_to_badly_shared_local); 649848690cfe9c59a8a92d4be6e5b43c77786066eephilippe if (ptr_to_badly_shared_local == NULL) 659848690cfe9c59a8a92d4be6e5b43c77786066eephilippe ptr_to_badly_shared_local = &badly_shared_local; 669848690cfe9c59a8a92d4be6e5b43c77786066eephilippe pthread_mutex_unlock(&protect_ptr_to_badly_shared_local); 679848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 689848690cfe9c59a8a92d4be6e5b43c77786066eephilippe for(i = 0; i < NLEVEL2; i++) { 699848690cfe9c59a8a92d4be6e5b43c77786066eephilippe pthread_create(&threads[curthread++], NULL, level2, NULL); 709848690cfe9c59a8a92d4be6e5b43c77786066eephilippe } 719848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 729848690cfe9c59a8a92d4be6e5b43c77786066eephilippe for(i = 0; i < curthread; i++) 739848690cfe9c59a8a92d4be6e5b43c77786066eephilippe pthread_join(threads[i], NULL); 749848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 759848690cfe9c59a8a92d4be6e5b43c77786066eephilippe return 0; 769848690cfe9c59a8a92d4be6e5b43c77786066eephilippe} 779848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 789848690cfe9c59a8a92d4be6e5b43c77786066eephilippe#define NLEVEL1 3 799848690cfe9c59a8a92d4be6e5b43c77786066eephilippeint main(int argc, char*argv[]) 809848690cfe9c59a8a92d4be6e5b43c77786066eephilippe{ 819848690cfe9c59a8a92d4be6e5b43c77786066eephilippe pthread_t threads[NLEVEL1]; 829848690cfe9c59a8a92d4be6e5b43c77786066eephilippe int curthread = 0; 839848690cfe9c59a8a92d4be6e5b43c77786066eephilippe int i; 849848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 859848690cfe9c59a8a92d4be6e5b43c77786066eephilippe only_touch_stackvar = argc > 1; 869848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 879848690cfe9c59a8a92d4be6e5b43c77786066eephilippe for(i = 0; i < NLEVEL1; i++) { 889848690cfe9c59a8a92d4be6e5b43c77786066eephilippe pthread_create(&threads[curthread++], NULL, level1, NULL); 899848690cfe9c59a8a92d4be6e5b43c77786066eephilippe } 909848690cfe9c59a8a92d4be6e5b43c77786066eephilippe 919848690cfe9c59a8a92d4be6e5b43c77786066eephilippe fprintf(stderr, "starting join in main\n"); 929848690cfe9c59a8a92d4be6e5b43c77786066eephilippe fflush(stderr); 939848690cfe9c59a8a92d4be6e5b43c77786066eephilippe for(i = 0; i < curthread; i++) 949848690cfe9c59a8a92d4be6e5b43c77786066eephilippe pthread_join(threads[i], NULL); 959848690cfe9c59a8a92d4be6e5b43c77786066eephilippe fprintf(stderr, "finished join in main\n"); 969848690cfe9c59a8a92d4be6e5b43c77786066eephilippe fflush(stderr); 979848690cfe9c59a8a92d4be6e5b43c77786066eephilippe return 0; 989848690cfe9c59a8a92d4be6e5b43c77786066eephilippe} 999848690cfe9c59a8a92d4be6e5b43c77786066eephilippe#else 1009848690cfe9c59a8a92d4be6e5b43c77786066eephilippeint main() 1019848690cfe9c59a8a92d4be6e5b43c77786066eephilippe{ 1029848690cfe9c59a8a92d4be6e5b43c77786066eephilippe fprintf(stderr, "starting join in main\n"); 1039848690cfe9c59a8a92d4be6e5b43c77786066eephilippe fflush(stderr); 1049848690cfe9c59a8a92d4be6e5b43c77786066eephilippe /* do nothing */ 1059848690cfe9c59a8a92d4be6e5b43c77786066eephilippe fprintf(stderr, "finished join in main\n"); 1069848690cfe9c59a8a92d4be6e5b43c77786066eephilippe fflush(stderr); 1079848690cfe9c59a8a92d4be6e5b43c77786066eephilippe return 0; 1089848690cfe9c59a8a92d4be6e5b43c77786066eephilippe} 1099848690cfe9c59a8a92d4be6e5b43c77786066eephilippe#endif 110