QUOTE (dxp @ Oct 8 2015, 15:23)

Смутно припоминаю, что этот момент пристально рассматривался, и даже был вариант, когда сравнение было вынесено во встраиваемую функцию, объявленную с квалификатором volatile, но потом остался нынешний вариант. Подробностей не помню.
Значит так, появилась ясность в вопросе про волатильность, Сергей наставил на путь истинный.

Суть в следующем. Главная тонкость состоит в том, что (цитата Сергея):
QUOTE
enable_context_switch() происходит в одном потоке, а disable_context_switch() - уже в другом
CODE
void TKernel::sched()
{
uint_fast8_t NextPrty = highest_priority(ReadyProcessMap);
if(NextPrty != CurProcPriority)
{
SchedProcPriority = NextPrty;
raise_context_switch();
do
{
enable_context_switch();
DUMMY_INSTR();
disable_context_switch();
}
while(CurProcPriority != SchedProcPriority); // until context switch done
}
}
Переменная
CurProcPriority в контексте каждого процесса фактически константа, точнее, не константа, конечно, но в условнии
CODE
while(CurProcPriority != SchedProcPriority);
происходит её чтение и с этого момента уже не важно, из памяти читать или из регистра, в данном процессе эта переменная не меняется
Переменная
SchedProcPriority является по сути признаком (меткой, тегом) следующего процесса. Если переключение контекстов произошло, т.е. поток управления прошёл через функцию
CODE
OS::TKernel::context_switch_hook(stack_item_t* sp)
где перед выходом выполняется
CODE
CurProcPriority = SchedProcPriority;
то мы оказываемся в "правильном" - т.е. в том, который был запланирован для переключения, - процессе, у которого его значение
CurProcPriority равно
SchedProcPriority, и даже если эта переменная закеширована в регистре, то это не мешает, т.к. для этого нового процесса это значение в регистре соответствует
SchedProcPriority, хотя операцией
CODE
CurProcPriority = SchedProcPriority;
это значение в регистр не заносилось. Иными словами, любой процесс, прошедший через
CODE
while(CurProcPriority != SchedProcPriority);
имеет в регистре это значение, которое у каждого процесса своё. Т.е. тут можно было бы вообще не
CurProcPriority использовать, а просто
Priority процесса, но
CurProcPriority в функциях ядра технически использовать проще (члены одного класса).
Волатильность для
SchedProcPriority нужна как раз по этой же причине: если компилятор закеширует значение этой переменной в регистре (см код функции), то после переключения контекста - т.е. в регистре из контекста другого процесса - будет лежать неверное значение: должно будет лежать значение, равное запланированному, которое в свою очередь равно приоритету процесса, на который произошло переключение, а будет лежать значение запланированного процесса, которое было загружено туда при прошлом переключении этого (на который переключились) процесса.