I have the following code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
char condA = 0;
volatile int vA = 0;
volatile int vB = 0;
void* thread_a(void* arg) {
while (1) {
if (1 == condA) {
vA += 1;
usleep(100);
} else {
;
// vB += 1;
// usleep(100);
}
}
return NULL;
}
void* thread_b(void* arg) {
condA = 1;
return NULL;
}
int main(void) {
pthread_t threadA;
pthread_t threadB;
if (0 != pthread_create(&threadA, NULL, thread_a, NULL)) {
return -2;
}
sleep(1);
if (0 != pthread_create(&threadB, NULL, thread_b, NULL)) {
return -1;
}
pthread_join(threadB, NULL);
sleep(1);
pthread_cancel(threadA);
printf("value A is %d\n", vA);
printf("value B is %d\n", vB);
return 0;
}
I run my gcc 5.4.0 with either -O0 and -O1.
On O0, the output is: value A is 501
On O1, the output is: value A is 0
I know that setting condA
to volatile will fix this, but why is it so? Why does the compiler optimize the condition if it is obviously set in another thread?
Also, if I uncomment the code in the else-statement, it works as expected.
A partial answer I found: https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Volatiles.html#Volatiles "C has the concept of volatile objects. These are normally accessed by pointers and used for accessing hardware or inter-thread communication.[...]"
But this does not explain the fact, that if I uncomment the code in the else statement the program will work with -O1.