Try to fix the flakyness of test11

This commit is contained in:
ptitSeb 2022-04-10 14:25:16 +02:00
parent 1c83a9f0b7
commit 74cd8cd6fe
2 changed files with 89 additions and 60 deletions

Binary file not shown.

View File

@ -8,95 +8,124 @@
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); \
fflush(stdout); \
exit(1); \
} \
#define checkResults(string, val) { \
if (val) { \
printf("Failed with %d at %s", val, string); \
exit(1); \
} \
}
/*
Use the keyword provided by pthread.h to delcare the following variable
is thread specific, i.e. it is only visible to a specific thread,
not shared/common to all thread.
These variables are stored in thread local storage (TLS) area.
Use the keyword provided by pthread.h to delcare the following variable
is thread specific, i.e. it is only visible to a specific thread,
not shared/common to all thread.
These variables are stored in thread local storage (TLS) area.
*/
__thread int TLS_data1 = 10;
__thread int TLS_data2 = 20;
__thread char TLS_data3[10];
// Sync, because it's needed apparently...
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t* mutex_ptr = &mutex;
static pthread_cond_t thread_state_cond = PTHREAD_COND_INITIALIZER;
static pthread_cond_t* thread_state_cond_ptr = &thread_state_cond;
static int status = 0;
#define NUMTHREADS 2
pthread_t thread[NUMTHREADS];
typedef struct {
int data1;
int data2;
int data1;
int data2;
} threadparm_t;
void *thread_run(void *parm)
{
int rc;
threadparm_t *gData;
int rc;
threadparm_t *gData;
printf("Thread %d: Entered (%d/%d)\n", (pthread_self()==thread[0])?1:2, TLS_data1, TLS_data2);
fflush(stdout);
pthread_mutex_lock(mutex_ptr);
if (pthread_self()==thread[0]) {
printf("Thread 1: Entered (%d/%d)\n", TLS_data1, TLS_data2);
fflush(stdout);
} else {
while (!status) pthread_cond_wait(thread_state_cond_ptr, mutex_ptr);
printf("Thread 2: Entered (%d/%d)\n", TLS_data1, TLS_data2);
fflush(stdout);
pthread_mutex_unlock(mutex_ptr);
status = 0;
pthread_cond_broadcast(thread_state_cond_ptr);
}
gData = (threadparm_t *)parm;
gData = (threadparm_t *)parm;
/* Assign the value from global variable to thread specific variable*/
TLS_data1 = gData->data1;
TLS_data2 = gData->data2;
strcpy(TLS_data3, "---");
TLS_data3[1] = (pthread_self()==thread[0])?'1':'2';
/* Assign the value from global variable to thread specific variable*/
TLS_data1 = gData->data1;
TLS_data2 = gData->data2;
strcpy(TLS_data3, "---");
TLS_data3[1] = (pthread_self()==thread[0])?'1':'2';
foo();
return NULL;
foo();
return NULL;
}
void foo() {
printf("Thread %d: foo(), TLS data=%d %d \"%s\"\n",
(pthread_self()==thread[0])?1:2, TLS_data1, TLS_data2, TLS_data3);
fflush(stdout);
while(!thread[1])
usleep(300);
if(pthread_self()==thread[0])
pthread_join(thread[1], NULL);
bar();
if (pthread_self()==thread[0]) {
printf("Thread 1: foo(), TLS data=%d %d \"%s\"\n", TLS_data1, TLS_data2, TLS_data3);
fflush(stdout);
status = 1;
pthread_cond_broadcast(thread_state_cond_ptr);
while (status) pthread_cond_wait(thread_state_cond_ptr, mutex_ptr);
pthread_mutex_unlock(mutex_ptr);
} else {
printf("Thread 2: foo(), TLS data=%d %d \"%s\"\n", TLS_data1, TLS_data2, TLS_data3);
fflush(stdout);
}
while(!thread[1])
usleep(300);
if(pthread_self()==thread[0])
pthread_join(thread[1], NULL);
bar();
}
void bar() {
printf("Thread %d: bar(), TLS data=%d %d \"%s\"\n",
(pthread_self()==thread[0])?1:2, TLS_data1, TLS_data2, TLS_data3);
fflush(stdout);
return;
printf("Thread %d: bar(), TLS data=%d %d \"%s\"\n",
(pthread_self()==thread[0])?1:2, TLS_data1, TLS_data2, TLS_data3);
fflush(stdout);
return;
}
int main(int argc, char **argv)
{
int rc=0;
int i;
threadparm_t gData[NUMTHREADS];
printf("Create/start %d threads\n", NUMTHREADS);
fflush(stdout);
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;
rc = pthread_create(&thread[i], NULL, thread_run, &gData[i]);
checkResults("pthread_create()\n", rc);
usleep(200);
}
//printf("Wait for all 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);
}
int rc=0;
int i;
threadparm_t gData[NUMTHREADS];
printf("Main completed\n");
return 0;
printf("Create/start %d threads\n", NUMTHREADS);
fflush(stdout);
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;
rc = pthread_create(&thread[i], NULL, thread_run, &gData[i]);
checkResults("pthread_create()\n", rc);
}
//printf("Wait for all 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);
}
thread_state_cond_ptr = NULL;
i = pthread_cond_destroy(&thread_state_cond);
checkResults("destroying cond\n", i);
mutex_ptr = NULL;
i = pthread_mutex_destroy(&mutex);
checkResults("destroying mutex\n", i);
printf("Main completed\n");
fflush(stdout);
return 0;
}