2016-06-07 2 views
1

У меня есть этот кусок коды C:Как выполнить небольшой фрагмент кода C атомарного

// ... many stuff here ... 
if (((*(ptr + 0xffce)) & 3)) { 
    *(ptr + 0xffce) |= 3; 
    *(ptr + 0xd415) = 1 << var; 
} 
// ... many stuff here ... 

где некоторые биты становятся логически связаны между собой и значением результата записывается в память.

Для моей программы очень важно, чтобы процессор не был поврежден во время выполнения этой части программы. Поэтому он должен быть выполнен атомал и вести себя так, чтобы блок кода был неделимым. Планировщику разрешается только отвлекать процессор до или после этого блока if.

Как достичь этого на нормальном экосистема Linux (с программой пользовательского пространства)?

РЕДАКТИРОВАТЬ: комментарии ниже указывают на то, что выполнение кода может оказаться невозможным, при этом CPU не может быть отвлечен планировщиком. Противоположный вопрос: - это вообще возможно достичь этой цели и что мне нужно сделать для этого?

+0

Использовать мьютексы? Таким образом, код пространства пользователя не может видеть память в несогласованном состоянии. –

+0

@KerrekSB Это не предотвратит перепланирование, AFAIK .. –

+1

@EugeneSh .: Нет, это не так, но из пользовательского пространства это все, что вы можете попросить. Планировщик не является тем, чье существование вы можете доказать из пользовательского пространства. –

ответ

1

В общем, записи в HW должны быть размещены в модулях ядра. Код, который вы показываете (записывает на hw-адреса), не будет работать в пользовательском пространстве, если платформа защищена MMU или другим управлением памятью. Теоретически, адресное пространство пользователя фактически отличается от адресного пространства ядра.

Когда в режиме ядра решение, скорее всего, представит его сам. В ядре много механизмов времени/защиты: preempt_disable, spin_locks, in_atomic, прерывания, высокоуровневые таймеры ядра, что угодно.

в целом вы можете добиться того, что вы пытаетесь сделать, отключив все прерывания на данной платформе. Обычно это означает RTOS или код ядра. (Отключение всех прерываний также предотвратит запуск планировщика.) Однако на большинстве платформ это неодобрительно. (Не без оснований.) Таким образом, вы должны сделать это в соответствии с правилами платформы. «Preempt_disable» - хороший пример того, как отключить планировщик, не отключая все остальное.