У меня есть следующий C код:
/* the memory entry points to can be changed from another thread but
* it is not declared volatile */
struct myentry *entry;
bool isready(void)
{
return entry->status == 1;
}
bool isready2(int idx)
{
struct myentry *x = entry + idx;
return x->status == 1;
}
int main(void) {
/* busy loop */
while (!isready())
;
while (!isready2(5))
;
}
Как я отмечаю в комментарии, запись не объявлена как volatile, хотя массив, на который она указывает, может быть изменен из другого потока (или даже непосредственно из пространства ядра).
Является ли приведенный выше код неправильным / небезопасным? Я думаю, что оптимизация не может быть выполнена в теле isready, isready2, и, поскольку я неоднократно выполняю вызовы функций из основного, соответствующая область памяти должна читаться при каждом вызове.
С другой стороны, компилятор мог бы встроить эти функции. Возможно ли, что это происходит таким образом, что в результате происходит одно чтение (следовательно, вызывает бесконечное l oop) вместо нескольких чтений (даже если эти чтения происходят из буфера загрузки / сохранения)?
И второй вопрос. Можно ли помешать компилятору выполнять оптимизацию путем преобразования в volatile только в определенных местах, подобных этому?
void func(void)
{
entry->status = 1;
while (((volatile struct myentry *) entry)->status != 2)
;
}
Спасибо.