2013-04-16 16 views
11

Wiele operacji C++ 11 CAS (np atomic_compare_exchange_weak, atomic_compare_exchange_strong) wziąć dwa wskaźniki i wartości, czyli tak:Dlaczego operacje C++ 11 CAS przyjmują dwa parametry wskaźnika?

bool atomic_compare_exchange(T* pointer, T* expected,  // pseudodeclaration! 
          T desired); 

Natomiast operacje CAS Microsoft, gcc i Intel wszystko wziąć jeden wskaźnik i dwie wartości:

long InterlockedCompareExchange(long* pointer, long desired,  // Microsoft 
           long expected); 

int __sync_bool_compare_and_swap (T* pointer, T expected,   // gcc and 
            T desired);      // Intel 

Dlaczego C++ 11 funkcje CAS trwać dwa wskaźniki i wartości, zamiast tego, co wydaje się być bardziej konwencjonalny jeden wskaźnik i dwie wartości?

+0

'__sync_bool _...' zwraca bool * *. –

+1

@KerrekSB: Podpis, który pokazałem skopiowałem z podręcznika Intela. Zakładam, że gcc używał tego samego podpisu. Teraz widzę, że tak nie jest. – KnowItAllWannabe

Odpowiedz

18

Sposób C++ 11 jest bardziej przydatny: Jeśli wymiana się nie powiedzie, to *expected jest zaktualizowana do nowej, bieżącej wartości. To sprawia, że ​​jest łatwy w użyciu funkcję w pętli:

T value = x.load(); 
T newvalue = frob(value); 

while (!atomic_compare_exchange(&x, &value, newvalue)) 
{ 
    newvalue = frob(value); 
} 

Z podpisem Microsoft, sprawdzając, czy operacja jest bardziej kłopotliwe udało, i to samo ale dla GCC __sync_type wersji. Z GCC __sync_bool, musisz nawet wykonać inne obciążenie za każdym razem, gdy wymiana się nie powiedzie.

2

Nie rozumiem, dlaczego nie mielibyście oboje. W moim przypadku użycia wersja C++ jest mniej przydatna. Chcę poczekać, aż zmienna ma jakąś wartość, a następnie ustawić ją na nową wartość.

Z instrinsics GCC:

while (!__sync_bool_compare_and_swap(&value, expected, desired)) { } 

z C++ 11:

auto tmp = expected; 
while (!value.compare_exchange_weak(tmp,desired)) 
{ 
    tmp = expected; 
}