-3

We know that Events such as AutoResetEvent and ManualResetEvent are simply Boolean variables maintained by the kernel. Compared with Events, Monitor has additional features such as thread ownership, and recursion lock , just like System.Threading.Mutex.

Does Monitor use the same boolean variable maintained by the kernel? If yes, then is Monitoris the same as Mutex in perspective or OS kernels?

Daniel Geyfman
  • 246
  • 1
  • 10
  • “ We know that Events such as AutoResetEvent and ManualResetEvent are simply Boolean variables maintained by the kernel.” - **no, they aren’t**. – Dai Jun 17 '21 at 11:26
  • The analogy to a bool is very weak. Monitor is a much more sophisticated sync object than an event. But under the hood it does indeed use the same OS primitive when blocking is required, not a mutex. A reading guide to the CLR code that implements Monitor [is here](https://stackoverflow.com/a/14923685/17034). – Hans Passant Jun 17 '21 at 12:19

1 Answers1

3

Monitor takes an object reference, an object has a special header the CLI uses to store information about the lock, and how it promotes the lock to a kernel event if needed.

Object header

The most significant bytes in a typical object header format is shown below.

|31            0|    
----------------| 
|7|6|5|4|3|2| --|
 | | | | | |
 | | | | | +- BIT_SBLK_IS_HASHCODE : set if the rest of the word is a hash code (or sync block index)
 | | | | +--- BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX : set if hashcode or sync block index is set
 | | | +----- BIT_SBLK_SPIN_LOCK : lock the header for exclusive mutation on spin
 | | +------- BIT_SBLK_GC_RESERVE : set if the object is pinned
 | +--------- BIT_SBLK_FINALIZER_RUN : set if finalized already
 +----------- BIT_SBLK_AGILE_IN_PROGRESS : set if locking on AppDomain 

Once you create a lock / Monitor on an object, the CLR will look at the header and first determine whether it needs to find any locking information in the Sync Block table, it does this simply by looking at the bits that are set. If there is no Thin Lock, it will create one (if applicable). If there is a Thin Lock it will try to spin and wait for it. If the header has been inflated, it will look in the Sync Block Table for locking information.

A Thin Lock basically consists of an App Domain Index, Recursion Level, and a Managed Thread Id. The Thread Id is atomically set by a locking thread if zero, or if nonzero, a simple spin wait is used to reread the lock state various times to acquire the lock. If after a period of time the lock is still not available, it will need to promote the lock (and if not already done so), inflate the Thin Lock to the Sync Block Table and a true* lock will need to be registered with the operating based on a Kernel Event (like an auto reset event).

Note this was an excerpt from a larger slightly related answer of mine, if you are extremely bored take a look here

Why Do Locks Require Instances In C#?

TheGeneral
  • 79,002
  • 9
  • 103
  • 141