Mail Archives: cygwin/2013/02/17/22:39:02
X-Recipient: | archive-cygwin AT delorie DOT com
|
X-SWARE-Spam-Status: | No, hits=1.5 required=5.0 tests=AWL,BAYES_00,DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,FSL_HELO_BARE_IP_2,NML_ADSP_CUSTOM_MED,RCVD_IN_DNSWL_NONE,RCVD_NUMERIC_HELO,RP_MATCHES_RCVD,SARE_SUB_ENC_UTF8,SPF_HELO_PASS
|
X-Spam-Check-By: | sourceware.org
|
To: | cygwin AT cygwin DOT com
|
From: | Zach Saw <zach DOT saw AT gmail DOT com>
|
Subject: | Weird threading / =?utf-8?b?X190aHJlYWQ=?= behavior
|
Date: | Mon, 18 Feb 2013 03:38:27 +0000 (UTC)
|
Lines: | 113
|
Message-ID: | <loom.20130218T042711-4@post.gmane.org>
|
Mime-Version: | 1.0
|
User-Agent: | Loom/3.14 (http://gmane.org/)
|
X-IsSubscribed: | yes
|
Mailing-List: | contact cygwin-help AT cygwin DOT com; run by ezmlm
|
List-Id: | <cygwin.cygwin.com>
|
List-Subscribe: | <mailto:cygwin-subscribe AT cygwin DOT com>
|
List-Archive: | <http://sourceware.org/ml/cygwin/>
|
List-Post: | <mailto:cygwin AT cygwin DOT com>
|
List-Help: | <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
|
Sender: | cygwin-owner AT cygwin DOT com
|
Mail-Followup-To: | cygwin AT cygwin DOT com
|
Delivered-To: | mailing list cygwin AT cygwin DOT com
|
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
- Raw text -