При написании системного ПО, не обязательно для встраиваемых систем необходимо быть уверенным, что программа скомпилирована и работает так, как написана, и "умный" компилятор при оптимизации не переставил или вообще выкинул "не нужные" на его взгляд инструкции.
Для этого применяется такая штука, как Memory Barrier.
Если мы используем GCC или GCC-совместимый компилятор, то может быть объявлен такой макрос:
#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" ) 

И тогда критические участки кода, например, работа со счетчиками блокировок планировщика в ОС могут быть
реализованы следующим образом:
HAL_REORDER_BARRIER();
shed_lock ++;
HAL_REORDER_BARRIER();
При оптимизации компилятор не анализирует код в ассемблерных макросах, поэтому когда он встречает макрос "asm" он понимает, что этот кусок оптимизировать не надо.

Кстати, Memory Barrier можно использовать и для более приземленных целей.
Например, надо записать число в регист контроллера...да хотя бы зажечь лампочку.
Делается это, например, при помощи такого макроса:
#define  WriteReg(addr,val) (*(volatile unsigned*)(addr)=val); 
таким образом:
WriteReg(LEDS_BASE + XGPIO_TRI_OFFSET, 0x1);         
  
С большой долей вероятности при включении оптимизации такой код будет выкинут. В этом случае можно определить таким образом:
#define  WriteReg(addr,val)  \
         HAL_REORDER_BARRIER();   \
         (*(volatile unsigned*)(addr)=val); \
         HAL_REORDER_BARRIER();
и все заработает =)  
  
Конкретная реализация макроса HAL_REORDER_BARRIER() будет отличаться для каждого компилятора.
Более подробно про Memory Barrier можно почитать хотя бы в википедии: http://en.wikipedia.org/wiki/Memory_barrier

Последнее изменение: Понедельник, 5 сентября 2011, 12:30