История изменений
Исправление firkax, (текущая версия) :
Да :) Так и было, а я почему-то без сначала отладчика, потом отладочных логов, потом отладочных логов с запоминанием обоих status2 - не догадался что происходит. Вот таких, вместо ассерта:
if(!(e1=obj->status2) || (e2=obj->status2)==4 && obj->data)) {
log ... e1 e2
exit(-1)
}
Но удивляет вот что: сравнение сначала с нулём, а затем с четвёркой - это почти соседние ассемблерные инструкции получаются. Интуитивно кажется, что вероятность между ними вклиниться status2=0;
исчезающе мала, однако на практике оно весьма себя проявляет. Конечно, даже если бы вероятность и правда была незаметной, это был бы совсем не повод оставлять этот баг, но то что он вот так себя заметно проявил - это удивительно. И, наверно, хорошо - ведь иначе он остался бы в коде и проявился когда-нить спустя годы, и пришлось бы вспоминать что там вообще происходит. Исправил добавлением write-lock1 вокруг status2=0;
.
но это если компилятор не взял на регистр status2… короче это место точно непонятное.
Там -O0, по крайней мере сейчас.
Исправление firkax, :
Да :) Так и было, а я почему-то без сначала отладчика, потом отладочных логов, потом отладочных логов с запоминанием обоих status2 - не догадался что происходит. Вот таких, вместо ассерта:
if(!(e1=obj->status2) || (e2=obj->status2)==4 && obj->data)) {
log ... e1 e2
exit(-1)
}
Но удивляет вот что: сравнение сначала с нулём, а затем с четвёркой - это почти соседние ассемблерные инструкции получаются. Интуитивно кажется, что вероятность между ними вклиниться status2=0;
исчезающе мала, однако на практике оно весьма себя проявляет. Конечно, даже если бы вероятность и правда была незаметной, это был бы совсем не повод оставлять этот баг, но то что он вот так себя заметно проявил - это удивительно. И, наверно, хорошо - ведь иначе он остался бы в коде и проявился когда-нить спустя годы, и пришлось бы вспоминать что там вообще происходит. Исправил добавлением write-lock1 вокруг status2=0;
.
Исходная версия firkax, :
Да :) Так и было, а я почему-то без сначала отладчика, потом отладочных логов, потом отладочных логов с запоминанием обоих status2 - не догадался что происходит. Вот таких, вместо ассерта:
if(!(e1=obj->status2) || (e2=obj->status2)==4 && obj->data)) {
log ... e1 e2
exit(-1)
}
Но удивляет вот что: сравнение сначала с нулём, а затем с четвёркой - это почти соседние ассемблерные инструкции получаются. Интуитивно кажется, что вероятность между ними вклиниться status2=0;
исчезающе мала, однако на практике оно весьма себя проявляет. Конечно, даже если бы вероятность и правда была незаметной, это был бы совсем не повод оставлять этот баг, но то что он вот так себя заметно проявил - это удивительно. И, наверно, хорошо - ведь иначе он остался бы в коде и проявился когда-нить спустя годы, и пришлось бы вспоминать что там вообще происходит. Исправил добавлением write-lock1 вокруг status2=0;
.