2011-06-17 110 views
1


我使用/ SunOS的通過在< SYS提供的原子操作atomic.h中>,這是
void *atomic_cas_ptr(volatile void *target, void *cmp, void *newval);

現在要提出的是可用的,我要檢查舊值是否由該返回函數和被調用函數cmp傳遞的參數是一樣的,如果是的話操作成功。
但我有一定的疑問:因爲這個函數返回一個無效指針到舊值讓我們把它叫做無效*舊的,我通過無效* cmp,然後我需要比較這兩個老和cmp,所以我要怎麼走比較這兩個?如果在比較*舊有變化,那麼我要做什麼?
實質上,我想要做的就是在另一個接受這三個參數並返回true或false,表示成功或失敗的函數內對此函數進行變形。
關於CAS,我讀到稱它爲無鎖操作是錯誤的,因爲它最終鎖定在硬件上(總線上鎖),它是正確的嗎?這就是CAS成本高昂的原因。原子操作實現

回答

2

函數聲明可能使您困惑。這個函數不會返回指向舊值(指什麼?)的指針,而是返回target指向的內存舊值(它應該是指向void *的指針,即void* volatile * target)。

通常,如果一個CAS原始返回舊值,而不是一個布爾值,你檢查CAS的成功像這樣的東西:

void* atomic_ptr; // global atomically modified pointer 

void* oldval, newval, comparand; // local variables 
/* ... */ 
oldval = atomic_cas_ptr((void*)&atomic_ptr, /* note that address is taken */ 
          comparand, newval); 
if(oldval == comparand) { 
    // success 
} else { 
    // failure 
} 

所以,當你比較old_val和比較字,你用局部變量,不工作同時更改(而全局atomic_ptr可能會再次更改),並且您比較指針值而不解除引用。

你想應該是這樣的功能:

bool my_atomic_cas_ptr(volatile void* target, void* comparand, void* newval) 
{ 
    return (comparand == atomic_cas_ptr(target, comparand, newval)); 
} 

應當注意,由於一些算法的舊值(CAS前一個)應該是已知的,最好是有一個CAS原始返回舊值而不是bool,因爲您可以輕鬆地從前者構建後者,而相反則更加複雜且效率低下(請參閱下面的代碼,試圖從返回bool的a MacOS CAS primitive中獲取正確的舊值)。

void* CAS(void* volatile* target, void* comparand, void* newval) 
{ 
    while(!OSAtomicCompareAndSwapPtr(comparand, newval, target)) { 
     void* snapshot = *target; 
     if(snapshot!=comparand) return snapshot; 
    } 
    return comparand; 
} 

至於CAS鎖定存儲器總線,它取決於硬件。對於舊的x86處理器來說是這樣,但在現代的x86系統中則不同。首先,沒有中央公共汽車;它被AMD的HyperTransport和Intel的QuickPath Interconnect取代。其次,在最近的CPU世代中,鎖定指令並不是全部被串行化(參見some data,其顯示不同存儲器地址上的鎖定指令不會干擾)。最後,在the commonly accepted definition鎖定自由是系統全面進步的保證,而不是缺少serializing synchronization

+0

完美:)我正在尋找,謝謝:-),以及您給出的鏈接都很棒:-) – peeyush 2011-06-20 05:12:03