[Mono-list] Class library developers: locking issues to keep in mind

Serge serge@wildwestsoftware.com
Mon, 29 Oct 2001 14:57:27 +0200

Thanks for the link Christian. I've seen the Pugh's papers on the topics,
but thanks anyway.

> it has never been a good time.
Yeah, exactly :)

> The primary issue I see here is that this simple code bloated
> dramatically. :)
Yes, it seems such code is next to impossible to comprehend :)

Well, to summarize a bit there are some topics to clarify:
1) For static fields, delayed initialization is supported by runtime:
   From Partition I, 8.9.5:
   If not marked BeforeFieldInit then that type's initializer method is
   executed at (i.e., is triggered by):
     * first access to any static or instance field of that type, or
     * first invocation of any static, instance or virtual method of that

So there is no need in DCL at all. The issue is to figure out how to
explicitly specify in the source code whether BeforeFieldInit is turned on
or off (currently explicitly coded static constructor forces CSC to omit the

2) It would be good to clarify lock semantics :-)
Notice that in Java there are explicit instructions to represent
synchronized blocks (monitorenter/monitorexit), while in C# it's just a
shortcut to invoke Threading.Monitor methods.
So it seems that while in Java releasing lock results in memory flushing,
this is not necessary true for .NET runtime.
At the same time, in Java there is no guarantee that operations after
monitorexit will be executed _after_ the lock is released. It's possible
that compiler will move them inside the synchronization braces.
So question is - is it guaranteed in NET that operators after lock {} won't
be moved inside the lock?

3) Another question is whether memory is flushed upon thread termination?

Also some compiler question.
Consider the following sequence:
     initializer  ();
     return singleton;

I think it's illegal for the compiler to emit the following bytecode:

     ldsfld object Singleton::singleton
     ldsfld native int Singleton::initializer
     calli void ()

because of the possible side-effects of calli?
Is this correct?