2009-05-02 15 views
10

Sono a conoscenza di operazioni atomiche built-in di GCC: http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Atomic-Builtins.htmlUn modo migliore per implementare un carico atomico generico o un archivio in GCC?

Ma questo elenco non comprende operazioni molto semplici, come il carico e memorizzare. Potrei attuare queste architetture limitati con assembly inline (in realtà per molti come x86 saranno fondamentalmente solo normale mov di), ma non c'è un modo migliore nel caso generale di qualcosa di simile:

// returns the value at ptr 
void *atomic_load_ptr(void **ptr) 
{ 
    return __sync_fetch_and_add(ptr, 0); 
} 

// returns old value int ptr after setting it to newval 
void *atomic_store_ptr(void **ptr, void *newval) 
{ 
    void *oldval = atomic_load_ptr(ptr) 
    void *oldval2; 
    do { 
     oldval2 = oldval; 
    } while ((oldval = __sync_val_compare_and_swap(ptr, oldval, newval)) != oldval2); 
    return oldval; 
} 
+0

Fermami se ho torto, ma la tua funzione "archivio" non è realmente un negozio in quanto restituisce il vecchio valore (quindi è molto vicino a CAS). – claf

+0

È davvero uno "scambio": memorizza un nuovo valore e restituisce il valore precedente se lo desideri. –

+0

Ho trovato che questa implementazione del carico ha un problema: non può essere utilizzata su memoria di sola lettura. – Mabus

risposta

2

Si potrebbe implementare mutex di basso livello con test_and_set. La funzione di carico è una buona imo, ma si memorizzare funzione dovrebbe utilizzare test_and_set invece di avere

while ((oldval = __sync_val_compare_and_swap(ptr, oldval, newval)) != oldval2); 

per evitare errori.

Problemi correlati