Intel Inspector meldet ein Datenrennen in meiner Spinlock-Implementierung

Ich habe ein sehr einfaches Spinlock mit den Interlocked-Funktionen in Windows erstellt und es auf einer Dual-Core-CPU getestet (zwei Threads, die eine Variable inkrementieren).

Das Programm scheint in Ordnung zu sein (es gibt jedes Mal das gleiche Ergebnis, was nicht der Fall ist, wenn keine Synchronisation verwendet wird), aberIntel Parallel Inspector sagt, dass es eine Rennbedingung bei gibtWert + = j (siehe den Code unten). Die Warnung verschwindet, wenn kritische Abschnitte anstelle von SpinLock verwendet werden.

Ist meine Implementierung von SpinLock korrekt oder nicht? Es ist wirklich seltsam, weil alle verwendeten Operationen atomar sind und die richtigen Speicherbarrieren haben und es nicht zu Rennbedingungen führen sollte.

class SpinLock
{
   int *lockValue;
   SpinLock(int *value) : lockValue(value) { }

   void Lock() {
      while(InterlockedCompareExchange((volatile LONG*)lockValue, 1, 0) != 0) {
          WaitABit();
      }
   }

   void Unlock() { InterlockedExchange((volatile LONG*)lockValue, 0); }
};

Das Testprogramm:

static const int THREADS = 2;
HANDLE completedEvents[THREADS];
int value = 0;
int lock = 0; // Global.

DWORD WINAPI TestThread(void *param) {
    HANDLE completed = (HANDLE)param;
    SpinLock testLock(&lock);

    for(int i = 0;i < 1000*20; i++) {
        for(int j = 0;j < 10*10; j++) {
            // Add something to the variable.
            testLock.Lock();
            value += j;
            testLock.Unlock();
        }
    }
    SetEvent(completed);
}

int main() {
   for(int i = 0; i < THREADS; i++) {
        completedEvents[i] = CreateEvent(NULL, true, false, NULL);
   }
   for(int i = 0; i < THREADS; i++) {
        DWORD id;
        CreateThread(NULL, 0, TestThread, completedEvents[i], 0, &id);
   }

   WaitForMultipleObjects(THREADS, completedEvents, true, INFINITE);
   cout<<value;
}

Antworten auf die Frage(3)

Ihre Antwort auf die Frage