Is function call an effective memory barrier for modern platforms?

后端 未结 4 1253
盖世英雄少女心
盖世英雄少女心 2020-12-04 11:12

In a codebase I reviewed, I found the following idiom.

void notify(struct actor_t act) {
    write(act.pipe, \"M\", 1);
}
// thread A sending data to thread          


        
4条回答
  •  北海茫月
    2020-12-04 11:47

    The basic rule is: the compiler must make the global state appear to be exactly as you coded it, but if it can prove that a given function doesn't use global variables then it can implement the algorithm any way it chooses.

    The upshot is that traditional compilers always treated functions in another compilation unit as a memory barrier because they couldn't see inside those functions. Increasingly, modern compilers are growing "whole program" or "link time" optimization strategies which break down these barriers and will cause poorly written code to fail, even though it's been working fine for years.

    If the function in question is in a shared library then it won't be able to see inside it, but if the function is one defined by the C standard then it doesn't need to -- it already knows what the function does -- so you have to be careful of those also. Note that a compiler will not recognise a kernel call for what it is, but the very act of inserting something that the compiler can't recognise (inline assembler, or a function call to an assembler file) will create a memory barrier in itself.

    In your case, notify will either be a black box the compiler can't see inside (a library function) or else it will contain a recognisable memory barrier, so you are most likely safe.

    In practice, you have to write very bad code to fall over this.

提交回复
热议问题