Czy mutex_unlock działa jako ogrodzenie pamięci?

Sytuacja, którą opiszę, ma miejsce na iPadzie 4 (ARMv7s), używając libów posix do blokowania / odblokowywania muteksu. Widziałem podobne rzeczy na innych urządzeniach ARMv7 (patrz poniżej), więc przypuszczam, że każde rozwiązanie będzie wymagało bardziej ogólnego spojrzenia na zachowanie muteksów i ogrodzeń pamięci dla ARMv7.

Pseudo kod scenariusza:

Wątek 1 - tworzenie danych:

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();
}

Wątek 2 - pobieranie danych:

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

Wcześniej (gdy problem pojawił się na iPadzie 2), wierzyłem w tomSharedProducerIndex = TempProducerIndex nie był wykonywany atomowo, a zatem zmieniono go na użycieAtomicCompareAndSwap przypisaćmSharedProducerIndex. To działało do tego momentu, ale okazało się, że się myliłem i błąd wrócił. Myślę, że „poprawka” zmieniła tylko trochę czasu.

Doszedłem do wniosku, że faktycznym problemem jest nieuporządkowane wykonywanie zapisów w blokadzie mutexów, tj. Jeśli kompilator lub sprzęt postanowili zmienić kolejność:

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

... do:

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 

... a następnie konsument przeplatał producenta, dane nie byłyby jeszcze zapisane, gdy konsument próbował je odczytać.

Po przeczytaniu barier pamięci pomyślałem więc, że spróbuję przenieść sygnał do konsumenta pozamutex_unlock, wierząc, że odblokowanie wytworzy barierę pamięci / ogrodzenie, które zapewnimSharedArray napisano do:

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

To jednak nadal się nie udaje i prowadzi mnie do pytania, czymutex_unlock na pewno będzie działać jako ogrodzenie do pisania, czy nie?

Czytałem teżartykuł od HP który sugerował, że kompilatory mogą przenosić kod do (ale nie z)crit_secs. Więc nawet po powyższej zmianie, piszęmSharedProducerIndex może być przed barierą. Czy jest jakiś przebieg tej teorii?

Dodając wyraźne ogrodzenie, problem zniknie:

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

Dlatego myślę, że rozumiem ten problem i że wymagane jest ogrodzenie, ale każdy wgląd w zachowanie odblokowania i dlaczego nie wydaje się, aby wykonywał barierę, byłby naprawdę użyteczny.

EDYTOWAĆ:

Jeśli chodzi o brak muteksu w wątku konsumenckim: polegam na zapisieint mSharedProducerIndex będąc pojedynczą instrukcją, a zatem mając nadzieję, że konsument przeczyta nową lub starą wartość. Albo są ważnymi stanami i zapewniają tomSharedArray jest napisany w kolejności (tj. przed napisaniemmSharedProducerIndex) byłoby OK, ale z tego, co do tej pory powiedziano, nie mogę na to odpowiedzieć.

Zgodnie z tą samą logiką wydaje się, że obecne rozwiązanie barierowe jest również wadliwe, podobnie jakmSharedProducerIndex zapis może zostać przeniesiony do wnętrza bariery i dlatego może zostać nieprawidłowo uporządkowany.

Czy zaleca się dodanie muteksu do konsumenta, aby działać jako bariera odczytu, czy też istniejepragma lub instrukcja wyłączenia wykonania poza zamówieniem u producenta, jakEIEIO na PPC?

questionAnswers(2)

yourAnswerToTheQuestion