Possible to use C11 fences to reason about writes from other threads?

天涯浪子 提交于 2019-12-06 14:22:58

You forget memory_order_acquire fence in p3:

void
p3(void *_ignored)
{
  int register1 = 1;
  if (atomic_load_explicit(&b, memory_order_relaxed)) {
    atomic_thread_fence(memory_order_acquire); // <-- Here
    register1 = atomic_load_explicit(&a, memory_order_relaxed);
  }
  assert(register1 != 0);
}

With this fence, loading a in p2 will be in happens-before relation with loading a in p3.

C11 standard garantees read-read coherence, which means that the loading in p3 should observe same-or-subsequent modification, which is observed by the happened-before loading in p2. Because the loading in p2 observes the store in p1, and no subsequent modifications of a is possible in your scenario, loading in p3 should also observe storing in p1.

So your assertion can never trigger.


References to the corresponded statements in the standard:

5.1.2.4 p.25: The execution of a program contains a data race if it contains two conflicting actions in different threads, at least one of which is not atomic, and neither happens before the other. Any such data race results in undefined behavior.

So, atomic accesses cannot contain data race by definition.

5.1.2.4 p.22: ... if a value computation A of an atomic object M happens before a value computation B of M, and the value computed by A corresponds to the value stored by side effect X, then the value computed by B shall either equal the value computed by A, or be the value stored by side effect Y, where Y follows X in the modification order of M.

Next paragraph says, that this is cache coherence garantee. C++11 standard is more specific, and says about read-read cache coherence in similar wording.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!