Daily WTF

vall

#include <stdio.h>
#include <pthread.h>

volatile int x;
volatile int a, b;
int g;

void *a_fn(void *data)
{
while (1) {
if (--x == 0)
a = 1;
}
}

void *b_fn(void *data)
{
while (1) {
if (--x == 0)
b = 1;
}
}

int main(int argc, char **argv)
{
pthread_t a_th;
pthread_t b_th;

pthread_create(&a_th, NULL, a_fn, NULL);
pthread_create(&b_th, NULL, b_fn, NULL);

while (1) {
if (x < 0) {
if (a && b)
printf("Boom! %d\n", g);
a = b = 0;
x = 2;
g++;
}
}
}

если убрать один или оба volatile то gcc начнёт оптимизировать вплоть до пустого цикла.
для "x" понятно, но почему он решает выбросить присваивание a и b?

apl13

А где у тебя x инициализируется? Я тоже не вижу.

procenkotanya

Я не понимаю, что ты не понимаешь. Для каких не-volatil'ов какие циклы вызывают вопросы?
(dizzyden: x глобальный вообще-то, какая тебе нужна инициализация?)

vall

убери оба volatile и собери с -O1

vall

на самом деле всё тут просто. цикл бесконечный и барьеров нет так что компилятор считает что новые значения всё равно никто не увидит и редуцирует тело цикла до пустого

vall

ну и пример кода который таки работает :grin:
#include <pthread.h>
#include <atomic>
#include <stdio.h>

volatile std::atomic <int> x;
volatile std::atomic <int> a, b, g(1);

void *a_fn(void *data)
{
while (1) {
int t = g;
if (--x == 0)
a = t;
}
}

void *b_fn(void *data)
{
while (1) {
int t = g;
if (--x == 0)
b = t;
}
}

int main(int argc, char **argv)
{
pthread_t a_th;
pthread_t b_th;

pthread_create(&a_th, NULL, a_fn, NULL);
pthread_create(&b_th, NULL, b_fn, NULL);

while (1) {
if (x <= 0) {
if (a == g && b == g)
printf("Boom! %d\n", (int)g);
g++;
x = 2;
}
}
}

Maurog

volatile std::atomic <int> x;
volatile тут зачем?
работает = "печатает Boom" ?

vall

артефакт остался
работает == не печатает

Maurog

артефакт остался
работает == не печатает
фух, а я уж напрягся :grin: :grin:
Оставить комментарий
Имя или ник:
Комментарий: