2

In c++11, can std::atomic be used to transmit non-atomic data between two thread? In detail, are the following 4 semantics all established by atomic?

  1. all statements(when talking about execution, including all machine instructions generated by those c++ statements) before an atomic-write statement are executed before the atomic-write.

  2. all statements(when talking about execution, including all machine instructions generated by those c++ statements) after an atomic-read are executed after the atomic-read.

  3. all other memory-write before writing an atomic are committed to main memory.

  4. all other memory-read after reading an atomic will read from main memory again(that means discard thread cache).

I have seen an example here: http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/

However, in the example, the data is an atomic, so my question is, what if the data is non-atomic?

Here is some code, showing what i want:

common data:

std::atomic_bool ready;
char* data; // or data of any other non atomic

write thread:

data = new char[100];
data[0] = 1;
ready.store(true); // use default memory_order(memory_order_seq_cst), witch i think is the most restrict one

read thread:

if(ready.load()) { // use default memory_order(memory_order_seq_cst)
    assert(data[0] == 1); // both data(of type char*) and data[0~99](each of type char) are loaded
}
autumn
  • 172
  • 1
  • 1
  • 10

1 Answers1

1

I think you must use memory orders:

data = new char[100];
data[0] = 1;
ready.store_explicit(true, std::memory_order_release);

if(ready.load_explicit(std::memory_order_aqcuire)) {
    assert(data[0] == 1); // both data(of type char*) and data[0~99](each of type char) are loaded
}

(i am not sure about this syntax _explicit)

Actually your code is correct, but in this case there is no need to sec/cst memory order and acquire/release is correct. with release no write can be reordered after atomic write and with acquire no load can be reordered before atomic load, so all non-atomic store before atomic store will be visible to all loads after atomic load.

MRB
  • 3,752
  • 4
  • 30
  • 44
  • 8
    Default memory order is `memory_order_seq_cst` which is even more restrictive than `acquire/release`. – Stephan Dollberg Oct 30 '13 at 11:30
  • @bamboon Oh, yes you are right, but i think either way is correct, not? – MRB Oct 30 '13 at 11:32
  • Yes, I think acq/rel should be enough as it guarantees that all writes become visible in the other thread. – Stephan Dollberg Oct 30 '13 at 11:35
  • There are free functions with `_explicit` (such as `atomic_load_explicit`) but no member functions with that suffix. Just use `.store` and `.load` – dyp Oct 30 '13 at 11:43