Для создания страницы грязной (включение грязного бита в записи таблицы страниц), я касаюсь первых байтов страницы как это:
pageptr[0] = pageptr[0];
Но на практике gcc проигнорирует оператор мертвым устранением хранилища. Для предотвращения gcc оптимизация его я переписываю оператор следующим образом:
volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;
Это кажется работами приема, но несколько ужасный. Я хотел бы знать, там какие-либо директивы или синтаксис, который имеет тот же эффект? И я не хочу использовать a -O0
флаг, так как это принесет штраф высокой эффективности также.
Отключение оптимизации решает проблему, но в этом нет необходимости. Более безопасная альтернатива - запретить компилятору оптимизировать хранилище с помощью квалификатора типа volatile
.
// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];
Квалификатор типа volatile
указывает компилятору строго соблюдать требования к хранению и загрузке памяти. Одна из целей volatile
- сообщить компилятору, что доступ к памяти имеет побочные эффекты и, следовательно, должен быть сохранен. В этом случае хранилище имеет побочный эффект, вызывающий ошибку страницы, и вы хотите, чтобы компилятор сохранил ошибку страницы.
Таким образом, окружающий код все еще может быть оптимизирован, и ваш код переносится на другие компиляторы, которые не понимают синтаксис GCC #pragma
или __ attribute __
.
Вы можете использовать
#pragma GCC push_options
#pragma GCC optimize ("O0")
your code
#pragma GCC pop_options
, чтобы отключить оптимизацию, начиная с GCC 4.4.
Если вам нужны более подробные сведения, см. Документацию GCC.