2015-07-02 7 views
8

Ho trovato questo codice per compareAndSwap in a StackOverflow answer:Come posso implementare un puntatore portatile confrontare e scambiare?

boolean CompareAndSwapPointer(volatile * void * ptr, 
           void * new_value, 
           void * old_value) { 
#if defined(_MSC_VER) 
    if (InterlockedCompareExchange(ptr, new_value, old_value) == old_value) return false; 
    else return true; 
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 
    return __sync_bool_compare_and_swap(ptr, old_value, new_value); 
#else 
# error No implementation 
#endif 
} 

È questo il modo più corretto di avere codice veloce portatile, (tranne assemblaggio inline).

Inoltre, un problema è che questi specifici metodi builtin hanno parametri diversi e valori di ritorno da un compilatore a un altro, il che potrebbe richiedere alcune modifiche aggiuntive come lo if then else in questo esempio.

Un altro problema potrebbe essere il comportamento di questi metodi builtin a livello di codice macchina, si comportano esattamente nello stesso modo? (Per esempio utilizzano le stesse istruzioni di montaggio)

Nota: altro problema sarebbe se c'è molte piattaforme supportate non solo (Windows e Linux) come in questo esempio. Il codice potrebbe diventare molto grande.

+1

_ "È questo il modo più corretto per avere un codice veloce portatile, (eccetto l'inlining di assemblaggio)." _ L'assemblaggio in linea sarebbe estremamente _non_-portable. – Michael

+1

'std :: atomico ' :-) –

+1

C o C++? Sceglierne uno. –

risposta

3

Vorrei utilizzare uno strato di astrazione hardware , (HAL) che consente di utilizzare codice generico e che qualsiasi sorgente portatile può essere inclusa e creata per ogni piattaforma.

A mio parere, questo consente una fonte più strutturata e più leggibile.

Per consentirvi di comprendere meglio questo processo, suggerirei a Google di trovare esempi e spiegazioni.

Speriamo che questa breve risposta sia d'aiuto.

[EDIT] cercherò un semplice esempio per Bionix, per mostrare come implementare un sistema di HAL ...

  • Mr A vuole che la sua applicazione da eseguire sul suo 'Tianhe-2' e anche la sua 'Amiga 500'. Ha i compilatori cross ecc e costruirà entrambi i binari sul suo PC. Vuole leggere i tasti e stampare sullo schermo.

mrAMainApplication.c contiene le seguenti ...

#include "hal.h" 

// This gets called every time around the main loop ... 
void mainProcessLoop(void) 
{ 
    unsigned char key = 0; 

    // scan key ... 
    key = hal_ReadKey(); 

    if (key != 0) 
    { 
     hal_PrintChar(key); 
    } 
} 

Si crea quindi un file di intestazione (Ricorda - questo è un esempio, non il codice di lavoro) ... Egli crea hal.h ...

#ifndef _HAL_H_ 
#define _HAL_H_ 

unsigned char hal_ReadKey(void); 
unsigned char hal_PrintChar(unsigned char pKey); 

#endif // _HAL_H_ 

Ora il signor a ha bisogno di due file di origine separati, uno per il suo sistema 'Tianhe-2' e un altro per il suo Amiga 500 ...

hal_A500.c

void hal_ReadKey(void) 
{ 
    // Amiga related code for reading KEYBOARD 
} 

void hal_PrintChar(unsigned char pKey) 
{ 
    // Amiga related code for printing to a shell... 
} 

hal_Tianhe2_VERYFAST.c

void hal_ReadKey(void) 
{ 
    // Tianhe-2 related code for reading KEYBOARD 
} 

void hal_PrintChar(unsigned char pKey) 
{ 
    // Tianhe-2 related code for printing to a shell... 
} 

Mr A poi - quando si costruisce per Amiga - costruisce mrAmainApplication.c e hal_A500.c Quando si costruisce per il Tianhe-2 - che usa hal_Tianhe2_VERYFAST.c invece di hal_A500.c

Giusto - Ho scritto questo esempio con un po 'di umorismo, questo non è segnato a chiunque, sento solo che rende l'esempio più interessante e, auspicabilmente, aiuta a capire.

Neil

+0

Ho cercato su Google, ma tutto quello che trovo sono informazioni generali su come funziona. Potresti darmi un collegamento ad un piccolo esempio usando il concetto di 'HAL', è implementato usando' C 'o' C++ ' – Bionix1441

+1

Mi dispiace Bionox1441, ma sono al lavoro - e abbiamo accesso limitato a internet . Ho notato (http://stackoverflow.com/questions/12700909/simple-example-to-illustrate-writing-an-abstraction-layer-in-c) questo potrebbe almeno dare una migliore comprensione del principale. Stasera guarderò per esempi migliori se questo non aiuta. – Neil

+0

Se potessi, per favore, darmi un esempio, ogni volta che hai tempo – Bionix1441

1

Date un'occhiata a ConcurrencyKit e, eventualmente, si può usare primitive di livello superiore che è probabilmente ciò che la maggior parte del tempo la gente vuole veramente. A differenza di HAL, che in qualche modo specifica del sistema operativo, credo che CK funzioni su Windows e con un numero di compilatori non Gcc.

Ma se si è interessati solo a come implementare "confronta-e-swap" o azioni atomiche su una vasta gamma di compilatori C, guarda e guarda come funziona quel codice. È tutto open-source.

Ho il sospetto che i dettagli possano diventare disordinati e non sono qualcosa che in generale creerà per esposizione facile o interessante per il pubblico in generale.

+0

ConcurrencyKit è molto specifico per questi casi concomitanti, ma la mia domanda prima che fosse modificata da un utente è generale non solo per il confronto e lo scambio. Ho usato come esempio di chiarimento per il problema che attualmente ho – Bionix1441

+1

Vedere la risposta rivista. – rocky

1

Nella moderna C, a partire da C11, utilizzare _Atomic per la qualifica del tipo e atomic_compare_exchange_weak per la funzione.

Le versioni più recenti di gcc e clang sono conformi a C11 e implementano queste operazioni in modo portatile.

+0

è il metodo 'atomic_compare_exchange_weak' veloce come' __sync_bool_compare_and_swap'. Il primo è una funzione normale, mentre il secondo è un metodo 'builtin' in gcc, quindi presumo che il secondo sia più veloce del primo. – Bionix1441

+0

Microsoft non usa la C moderna - questo non sarebbe d'aiuto. – Neil

+0

@Neil, penso di sì. Riduce il numero di casi di piattaforme esotiche per le quali devi codificare un'eccezione a 1, questa è l'idea degli standard. Inoltre, ci sono implementazioni di '' per MS, l'intera interfaccia è stata inventata originariamente per una libreria su Windows. –

Problemi correlati