Intel Inspector reporta una carrera de datos en mi implementación de spinlock

Hice un spinlock muy simple usando las funciones de Enclavamiento en Windows y lo probé en una CPU de doble núcleo (dos hilos que incrementan una variable);

El programa parece funcionar bien (siempre da el mismo resultado, que no es el caso cuando no se usa la sincronización), peroInspector paralelo de Intel dice que hay una condición de carrera envalor + = j (ver el código de abajo). La advertencia desaparece cuando se utilizan las secciones críticas en lugar de mi SpinLock.

¿Mi implementación de SpinLock es correcta o no? Es realmente extraño, porque todas las operaciones utilizadas son atómicas y tienen las barreras de memoria adecuadas y no deberían conducir a condiciones de carrera.

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

El programa de prueba:

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

Respuestas a la pregunta(3)

Su respuesta a la pregunta