Question

Since it appears that context switch may happen at any point in execution of instructions I am now wondering why code "in part in question" (those 2 instructions) makes sense, if context switch can happen between any instructions and we may be on different CPU core in second instruction.

void B()
  {
    Thread.MemoryBarrier();    // Barrier 3
    if (_complete)
    {
      //PART IN QUESTION
      Thread.MemoryBarrier();       // Barrier 4
      Console.WriteLine (_answer);
      //END PART IN QUESTION
    }
  }

Description on MemoryBarrier here doesn't appear to give guarantees MemoryBarrier that CPUs won't be switched after calling it.

(this is related to this question)

Was it helpful?

Solution

What guarantees that context-switch will not happen after Thread.MemorryBarrier() call?

Nothing. MemoryBarriers does not prevent context switching, (or atomic execution of your code).

As to your other question, why Barrier 4 is needed:

In the example code from the previous question, the C# compiler, CLR or the CPU might reorder reading of the answer variable before the completed variable if barrier 4 was not there. i.e. the code that actually runs could be similar to:

Thread.MemoryBarrier();    // Barrier 3
int tmpanswer = _answer;
if (_complete)
{

  Console.WriteLine (tmpanswer);
}

A barrier before the Console.WriteLine() will prevent reading _answer before reading _completed

But keep in mind that the code example only provides this one guarantee about the code in void B() (provided A() is run only once )

  • If the _complete variable is true , then Console.WriteLine will write out 123 and not 0.

So, unless A and B are run serially, the code does not provide any locking/notification such that B will always print 123. A() and B() could be interleaved/interrupted any time in its execution - you have no control over who gets to run when.

There is no guarantee that B() runs after A(), no matter which order you started the 2 threads in. (Though somewhere else in the code , you could start A() first and wait explicitly for it to finish before starting B() ofcourse)

OTHER TIPS

There are no guarantees that a context switch will or won't happen around a MemoryBarrier. These are orthogonal concepts.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top