Durante il porting di un codice Windows C++ su iOS, è necessario fornire un'implementazione della chiamata long InterlockedIncrement(long *p)
di Win32. Questo è abbastanza facile utilizzando le funzioni definite in <libkern/OSAtomic.h>
.Come implementare un incremento atomico di un puntatore su un numero intero utilizzando C++ 11 <atomic>?
Tuttavia, mi chiedo se sia possibile scriverlo in modo indipendente dall'OS utilizzando semplicemente la funzione C++ 11, principalmente <atomic>
. Sono arrivato con questo, che non sono sicuro realizza ciò che voglio:
inline long InterlockedIncrement(long* p)
{
std::atomic<long&> atomicP(*p);
return ++atomicP;
}
Funziona? È abbastanza buono? Le due linee non sono atomiche, ma l'incremento dovrebbe essere atomico, che è la chiave qui.
Tutti gli esempi di utilizzo per <atomic>
che ho trovato sono diversi, in cui uno std::atomic<T>
è definito e utilizzato direttamente. Qui voglio utilizzare una variabile lunga esistente che i chiamanti mi passano per indirizzo. Non sono riuscito a trovare un simile esempio.
Modifica: Clang 3.2 (in Xcode 4.x) non riesce a compilare ++atomicP
con l'errore "non è possibile incrementare il valore di tipo std::atomic<long&>
" (né atomicP += 1
).
Quale sarebbe il modo corretto?
Edit di nuovo: un'implementazione puntatore compila ...
inline long InterlockedIncrement(long* p)
{
std::atomic<long*> atomicP(p);
return ++(*atomicP);
}
ma ho paura che questo non funziona, dal momento che non incrementare un tipo atomico, ma il valore puntato dal puntatore, che non è atomico.
Non penso che si possa avere un 'atomico'. E la versione del puntatore è sbagliata (il puntatore memorizzato stesso sarà atomico, non il valore puntato). –
interjay
No, questo non funzionerà affatto senza cose specifiche dell'implementazione. –
Forse è il momento di convertirlo in 'std :: atomic' per la porta? Considerando che 'long' ha dimensioni diverse su Windows e OSX, probabilmente dovrai comunque fare qualcosa di specifico per il sistema operativo. –