Работает ли mutex_unlock как забор памяти?

Ситуация яОпишу, что происходит на iPad 4 (ARMv7s), используя posix libs для блокировки / разблокировки мьютекса. Я'хотя мы видели подобные вещи на других устройствах ARMv7 (см. ниже), поэтому я полагаю, что любое решение потребует более общего взгляда на поведение мьютексов и ограничений памяти для ARMv7.

Псевдокод для сценария:

Тема 1 - Производство данных:

void ProduceFunction() {
  MutexLock();
  int TempProducerIndex = mSharedProducerIndex; // Take a copy of the int member variable for Producers Index
  mSharedArray[TempProducerIndex++] = NewData; // Copy new Data into array at Temp Index 
  mSharedProducerIndex = TempProducerIndex; // Signal consumer data is ready by assigning new Producer Index to shared variable
  MutexUnlock();
}

Тема 2 - Потребление данных:

void ConsumingFunction () {
  while (mConsumerIndex != mSharedProducerIndex) {
    doWorkOnData (mSharedArray[mConsumerIndex++]);
  }
}

Ранее (когда проблема возникла на iPad 2), я считал, чтоmSharedProducerIndex = TempProducerIndex не выполнялся атомарно, и, следовательно, был изменен на использованиеAtomicCompareAndSwap назначитьmSharedProducerIndex, До этого момента это работало, но оказалось, что я ошибся, и ошибка вернулась. Я думаю,исправить» просто изменил некоторые сроки.

Теперь я пришел к выводу, что фактическая проблема заключается в неупорядоченном выполнении записей в пределах блокировки мьютекса, т.е. если компилятор или аппаратное обеспечение решили изменить порядок:

mSharedArray[TempProducerIndex++] = NewData; // Copy new Data into array at Temp Index 
mSharedProducerIndex = TempProducerIndex;  // Signal consumer data is ready by assigning new Producer Index to shared variable

... для:

mSharedProducerIndex = TempProducerIndex; // Signal consumer data is ready by assigning new Producer Index to shared variable
mSharedArray[TempProducerIndex++] = NewData; // Copy new Data into array at Temp Index 

... и тогда потребитель чередовал производителя, данные еще не были бы записаны, когда потребитель пытался их прочитать.

После некоторого чтения о барьерах памяти я подумал, чтопопробуйте передать сигнал потребителю за пределыmutex_unlockполагая, что разблокировка создаст барьер памяти / забор, который обеспечитmSharedArray было написано:

mSharedArray[TempProducerIndex++] = NewData;  // Copy new Data into array at Temp Index 
MutexUnlock();
mSharedProducerIndex = TempProducerIndex; // Signal consumer data is ready by assigning new Producer Index to shared variable

Это, однако, все еще терпит неудачу, и приводит меня к вопросу, еслиmutex_unlock определенно будет выступать в роли защитного ограждения или нет?

мы также читалистатья от HP который предполагал, что компиляторы могут перемещать код в (но не из)crit_secs. Так что даже после вышеуказанного изменения, записьmSharedProducerIndex может быть до барьера. Есть ли пробег этой теории?

При добавлении явного ограждения проблема исчезает:

mSharedArray[TempProducerIndex++] = NewData; // Copy new Data into array at Temp Index 
OSMemoryBarrier();
mSharedProducerIndex = TempProducerIndex; // Signal consumer data is ready by assigning new Producer Index to shared variable

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

РЕДАКТИРОВАТЬ:

Что касается отсутствия мьютекса в потоке потребителей: яЯ полагаюсь на записьint mSharedProducerIndex будучи единственной инструкцией и, следовательно, надеясь, что потребитель прочитает либо новое, либо старое значение. Либо действительные состояния, и при условии, чтоmSharedArray написано в последовательности (т.е. до написанияmSharedProducerIndex) это было бы хорошо, но из того, что было сказано до сих пор, я могуT ответить на это.

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

Рекомендуется ли добавить мьютекс потребителю, просто чтобы он выступал в качестве барьера для чтения, или естьpragma или инструкция по отключению внепланового исполнения на производителе, напримерEIEIO на ппц?

Ответы на вопрос(2)

Ваш ответ на вопрос