2017-03-20 20 views
1

this file中,boost::lockfree::detail::freelist類用於使用free list來管理用於無鎖數據結構(例如,隊列)的存儲。 deallocate_impl方法用於通過將節點鏈接回空閒列表來釋放節點(釋放節點成爲空閒列表的新頭部,替換舊頭部)。該方法應該是線程安全的並且無鎖定的。一個實例的原始源代碼在這裏重複我的意見註釋指出可疑代碼(潛在的bug?):如果這不是boost :: lockfree :: detail :: freelist中的錯誤,我在這裏丟失了什麼?

void deallocate_impl (index_t index) 
{ 
    freelist_node * new_pool_node = 
      reinterpret_cast<freelist_node*>(NodeStorage::nodes() + index); 

    // Shouldn't this line be placed inside the loop? 
    // The loop continues as long as the compare-and-exchange fails, 
    // which happens if the pool head has been concurrently updated. 
    // In that case, we MUST reload the new value of "pool_" to 
    // reuse its tag, link the new free-list head to it and 
    // compare against in the compare_and_exchange call. 
    tagged_index old_pool = pool_.load(memory_order_consume); 

    for(;;) { 
     // The old pool head tag is reused here without causing 
     // any ABA problems. However, if "index" is the same as 
     // old_pool.get_index(), a self-reference is written. 
     tagged_index new_pool (index, old_pool.get_tag()); 
     new_pool_node->next.set_index(old_pool.get_index()); 

     if (pool_.compare_exchange_weak(old_pool, new_pool)) 
      return; 
    } 
} 

我已經看到了升壓1.62.0太

+1

C++的一大缺點不表示引用成員在呼叫站點傳遞。比較交換更新預期值與當前可見值 – Voo

+0

謝謝@Voo。 –

回答

2
相同的實現

只要比較和交換失敗,循環就會繼續,如果池頭已被同時更新,就會發生這種情況。在這種情況下,我們必須重新加載「pool_」的新價值,以重用其標籤...

compare_exchange_weak()每次通話後寫的pool_前值到old_poolDocumentation for compare_exchange_weak()

但是,如果「指標」是一樣的old_pool.get_index()...

這恐怕是不可能發生的,因爲與該索引節點並沒有轉移到空閒列表呢。

+0

謝謝@Grisha。在發佈問題之前,我應該查閱文檔。 –

相關問題