Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <pre><code>inline operator T() { __sync_synchronize(); // Not sure this is overkill return obj; } </code></pre> <p>Short version: This IS overkill. </p> <p>Long version:</p> <p>Why do you want to implement this class as a template at all? It doesn't make sense because the atomic operations are allowed only on integer types from 1-8 bytes and you even can't be sure that an 8 byte integer is supported on all platforms.</p> <p>You should implement your atomic class as a non-template version and use the "native" integer type of your hardware/system. This is int32_t on 32 bit processors/os and int64_t on a 64 bit systems. e.g.:</p> <pre><code>#ifdef ... typedef ... native_int_type; #endif // verify that you choosed the correct integer type BOOST_STATIC_ASSERT(sizeof(native_int_type) == sizeof(void*)); </code></pre> <p>BOOST_STATIC_ASSERT is straight forward to "static_assert()" from C++0x.</p> <p>If you're using the "perfect fit" integer type you can write the operator just like that:</p> <pre><code>operator native_int_type() { return obj; } </code></pre> <p>Because obj is volatile it's guaranteed to fetch the value and not return any cached value. And because you're using the "native" integer type you can be sure that reading such a value is atomic.</p> <pre><code>atomic&amp; operator=( native_integer_type val ) </code></pre> <p>Again, you don't need a synchronize if you're using the right integer type. Read/Set an int32 on a intel 32 bit system is atomic and so is Read/Set an int64 on a 64 bit system.</p> <p>I don't see any benefit from implementing atomic as a template. Atomic operations are platform dependent. It's better to offer an "atomic_int" class that just guarantees to has at least 4 byte (if you're supporting 32bit and 64bit systems) and an "atomic_pointer" if you need it. This way the name of the class also implies a semantic and a purpose.</p> <p>If you just use "atomic" than one could think: "Wow, i just have to put my string class in this template and then it's thread safe!".</p> <hr> <p>Edit: to Answer your update: "I want to make sure that the operations are consistent in the face of read/write re-ordering due to compiler optimisations."</p> <p>To prevent compiler and cpu to reorder read/write operations you need the __sync_synchronize().</p> <p>But note that acquire/release semantics may yield better performance than full barriers.</p> <hr> <p>Edit2:</p> <pre><code>inline atomic&lt; T &gt; &amp; operator=( T val ) { __sync_synchronize(); // Not sure if this is overkill obj = val; return *this; } </code></pre> <p>What do you want prevent from reordering? In most cases you want to write this:</p> <pre><code> obj = val; __sync_synchronize(); </code></pre> <p>instead. Because you want to be sure that the value is written, once you returned from the function.</p>
    singulars
    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. 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.
    3. 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