The following test case fails on Cygwin but passes on Linux (both tested using GCC 4.7.2). There are two failures that this test case exposes -- first without commenting out the line "test = true;" and the second is with it commented out. The first case shows the variable 'test' is not being treated as a threadlocal var. In the second case, test will pass but fail sporadically on multi-core machines. If you mask CPU affinity out to enable just one core, it will pass 100% of the time. It shows a separate problem to case #1 (i.e. multithreaded apps will not run reliably on Cygwin). On my machine (Core2Duo), it fails on average once out of 5 runs.
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> void foo(void); /* Functions that use the TLS data */ void bar(void); #define checkResults(string, val) { \ if (val) { \ printf("Failed with %d at %s", val, string); \ exit(1); \ } \ } __thread int TLS_data1 = 0; __thread int TLS_data2 = 0; __thread bool test = false; #define NUMTHREADS 20 typedef struct { int data1; int data2; } threadparm_t; threadparm_t gResults[NUMTHREADS]; void *theThread(void *parm) { int rc; threadparm_t *gData; gData = (threadparm_t *)parm; sleep(1); if (!test) { test = true; // *** comment this out for test #2 TLS_data1 = gData->data1; TLS_data2 = gData->data2; } foo(); return NULL; } void foo() { gResults[TLS_data1].data1 = TLS_data1; bar(); } void bar() { gResults[TLS_data1].data2 = TLS_data2; } int main(int argc, char **argv) { pthread_t thread[NUMTHREADS]; int rc=0; int i; threadparm_t gData[NUMTHREADS]; printf("Enter Testcase - %s\n", argv[0]); for (i=0; i < NUMTHREADS; i++) { gResults[i].data1 = 0; gResults[i].data2 = 0; } printf("Create/start threads\n"); for (i=0; i < NUMTHREADS; i++) { /* Create per-thread TLS data and pass it to the thread */ gData[i].data1 = i; gData[i].data2 = (i+1)*2; printf("%d %d\n", gData[i].data1, gData[i].data2); rc = pthread_create(&thread[i], NULL, theThread, &gData[i]); checkResults("pthread_create()\n", rc); } printf("Wait for the threads to complete, and release their resources\n"); for (i=0; i < NUMTHREADS; i++) { rc = pthread_join(thread[i], NULL); checkResults("pthread_join()\n", rc); } for (i=0; i < NUMTHREADS; i++) { printf("gResults, data=%d %d\n", gResults[i].data1, gResults[i].data2); if (gResults[i].data1 != gData[i].data1) printf("failed\n"); if (gResults[i].data2 != gData[i].data2) printf("failed\n"); } printf("Main completed\n"); return 0; } Compile with: g++ tls_test.cpp -o tls_test.exe -lpthread Expected run outcome: no "failed" messages. -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple