Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Given types Key and T, the following code achieves the goal, assuming that type T is a type for which tbb::atomic is supported. </p> <pre><code>class AtomicValue { mutable tbb::atomic&lt;T&gt; content; public: AtomicValue() {} AtomicValue( T value ) {content=value;} bool cas( T value, T comparand ) const { return content.compare_and_swap(value,comparand)==comparand; } }; typedef tbb::concurrent_hash_map&lt;Key,AtomicValue&gt; table; bool update( table&amp; x, Key key, T value, T comparand ) { table::const_accessor a; if( !x.insert(a,table::value_type(key,value) ) ) { // value is already there return a-&gt;second.cas(value,comparand); } return true; } </code></pre> <p>The tricky part is using a const_accessor to do the update. Using a regular accessor would serialize the updates. But a const_accessor allows multiple threads to access the same table entry at the same time. It's called a "const_accessor" because the usual use case involves reading the value. But here the code uses CAS to arbitrate updates. The wrapper class "AtomicValue" enables doing CAS on a const object. </p> <p>A similar solution should work for tbb::concurrent_unordered_map, which might be better if non-blocking is the key criterion, because concurrent_unordered_map has a non-blocking implementation. </p> <p>Better yet, if you have the latest TBB <strong>and</strong> a compiler that supports the C++11 features of constexpr and defaulted/deleted member functions, the following should work:</p> <pre><code> typedef tbb::concurrent_unordered_map&lt;Key,tbb::atomic&lt;T&gt; &gt; table; bool update( table&amp; x, Key key, T value, T comparand ) { auto p = x.insert(table::value_type(key,value) ); if( !p.second ) { // value is already there return p.first-&gt;second.compare_and_swap(value,comparand) == comparand; } return true; } </code></pre> <p>It worked for me with gcc 4.7 when compiled with "g++ -std=c++0x".</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload