Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Thread.MemoryBarrier used here?

Browsing through the MEF source code I found this piece. Can somebody explain why MemoryBarrier is needed inside a lock?

The whole method is:

public void SatisfyImportsOnce(ComposablePart part)
{
    this.ThrowIfDisposed();

    if (this._importEngine == null)
    {
        ImportEngine importEngine = new ImportEngine(this, this._compositionOptions);

        lock(this._lock)
        {
            if (this._importEngine == null)
            {
                Thread.MemoryBarrier();
                this._importEngine = importEngine;
                importEngine = null;
            }
        }
        if(importEngine != null)
        {
            importEngine.Dispose();
        }
    }
    this._importEngine.SatisfyImportsOnce(part);
}
like image 834
Marko Devcic Avatar asked Sep 28 '15 13:09

Marko Devcic


1 Answers

Thread.MemoryBarrier prevents jitter/compiler any instructions reordering for code optimization.

In Treading in C#, by Joe Albahari book he sais:

  • The compiler, CLR, or CPU may reorder your program's instructions to improve efficiency.
  • The compiler, CLR, or CPU may introduce caching optimizations such that assignments to variables won't be visible to other threads right away.

In this example it might be that importEngine or _importEngine values are cached and it is very important that all threads has to be notified about changes right away.

Also MemoryBarrier in this case provides importEngine freshness garantee before it assigned to _importEngine

like image 104
Vlad Bezden Avatar answered Oct 15 '22 15:10

Vlad Bezden