Add a fourth parameter to the DEFINE_DACVAR macro that is the actual fully qualified...
[platform/upstream/coreclr.git] / src / vm / crst.h
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 //
5 // 
6 // CRST.H
7 //
8
9 // 
10 // Debug-instrumented hierarchical critical sections.
11 //
12 //
13 // The hierarchy:
14 // --------------
15 //    The EE divides critical sections into numbered groups or "levels."
16 //    Crsts that guard the lowest level data structures that don't
17 //    use other services are grouped into the lowest-numbered levels.
18 //    The higher-numbered levels are reserved for high-level crsts
19 //    that guard broad swatches of code. Multiple groups can share the
20 //    same number to indicate that they're disjoint (their locks will never
21 //    nest.)
22 //
23 //    The fundamental rule of the hierarchy that threads can only request
24 //    a crst whose level is lower than any crst currently held by the thread.
25 //    E.g. if a thread current holds a level-3 crst, he can try to enter
26 //    a level-2 crst, but not a level-4 crst, nor a different level-3
27 //    crst. This prevents the cyclic dependencies that lead to deadlock.
28 //
29 //    For debugging purposes Crsts are all also grouped by a type (e.g.
30 //    CrstRemoting, the type of Crst used to synchronize certain remoting
31 //    operations). Each type maps to one level (though a level may map to
32 //    multiple types). The idea here is for the programmer to express Crst types
33 //    and their dependencies (e.g. a CrstClassInit instance may be acquired
34 //    while a CrstRemoting instance is already held) in a high level manner
35 //    while an external script handles the mechanical process of assigning
36 //    numerical levels to each type. See file:..\inc\CrstTypes.def for these high level
37 //    type definitions.
38 //
39 //
40 // To create a crst:
41 //
42 //    Crst *pcrst = new Crst(type);
43 //
44 //      where "type" is one of the enums created in the auto-generated
45 //      file:..\inc\CrstTypes.h header file (matching the definition in
46 //      file:..\inc\CrstTypes.def).
47 //
48 //      By default, crsts don't support nested enters by the same thread. If
49 //      you need reentrancy, use the alternate form:
50 //
51 //    Crst *pcrst = new Crst(type, TRUE);
52 //
53 //      Since reentrancies never block the caller, they're allowed to
54 //     "violate" the level ordering rule.
55 //
56 //
57 // To enter/leave a crst:
58 // ----------------------
59 //
60 //
61 //    pcrst->Enter();
62 //    pcrst->Leave();
63 //
64 // An assertion will fire on Enter() if a thread attempts to take locks
65 // in the wrong order.
66 //
67 // Finally, a few DEBUG-only methods:
68 //
69 // To assert taking a crst won't violate level order:
70 // --------------------------------------------------
71 //
72 //    _ASSERTE(pcrst->IsSafeToTake());
73 //
74 //    This is a good line to put at the start of any function that
75 //    enters a crst in some circumstances but not others. If it
76 //    always enters the crst, it's not necessary to call IsSafeToTake()
77 //    since Enter() does this for you.
78 //
79 // To assert that the current thread owns a crst:
80 // --------------------------------------------------
81 //
82 //   _ASSERTE(pcrst->OwnedByCurrentThread());
83
84
85
86 #ifndef __crst_h__
87 #define __crst_h__
88
89 #include "util.hpp"
90 #include "debugmacros.h"
91 #include "log.h"
92
93 #define ShutDown_Start                          0x00000001
94 #define ShutDown_Finalize1                      0x00000002
95 #define ShutDown_Finalize2                      0x00000004
96 #define ShutDown_Profiler                       0x00000008
97 #define ShutDown_COM                            0x00000010
98 #define ShutDown_SyncBlock                      0x00000020
99 #define ShutDown_IUnknown                       0x00000040
100 #define ShutDown_Phase2                         0x00000080
101
102 #ifndef DACCESS_COMPILE
103 extern bool g_fProcessDetach;
104 extern DWORD g_fEEShutDown;
105 #endif
106 // Total count of Crst lock  of the type (Shutdown) that are currently in use
107 extern Volatile<LONG> g_ShutdownCrstUsageCount;
108 extern Volatile<LONG> g_fForbidEnterEE;
109 extern bool g_fFinalizerRunOnShutDown;
110
111 // The CRST.
112 class CrstBase
113 {
114 #ifndef CLR_STANDALONE_BINDER
115
116 // The following classes and methods violate the requirement that Crst usage be
117 // exception-safe, or they satisfy that requirement using techniques other than
118 // Holder objects:
119 friend class Thread;
120 friend class ThreadStore;
121 friend class ThreadSuspend;
122 friend class ListLock;
123 friend class ListLockEntry;
124 //friend class CExecutionEngine;
125 friend struct SavedExceptionInfo;
126 friend void EEEnterCriticalSection(CRITSEC_COOKIE cookie);
127 friend void EELeaveCriticalSection(CRITSEC_COOKIE cookie);
128 friend class ReJitPublishMethodHolder;
129 friend class ReJitPublishMethodTableHolder;
130
131 friend class Debugger;
132 friend class Crst;
133
134 #ifdef FEATURE_DBGIPC_TRANSPORT_VM
135     // The debugger transport code uses a holder for its Crst, but it needs to share the holder implementation
136     // with its right side code as well (which can't see the Crst implementation and actually uses a
137     // CRITICAL_SECTION as the base lock). So make DbgTransportSession a friend here so we can use Enter() and
138     // Leave() in order to build a shared holder class.
139     friend class DbgTransportLock;
140 #endif // FEATURE_DBGIPC_TRANSPORT_VM
141
142     // PendingTypeLoadEntry acquires the lock during construction before anybody has a chance to see it to avoid 
143     // level violations.
144     friend class PendingTypeLoadEntry;
145
146 public:
147 #ifdef _DEBUG
148     enum NoLevelCheckFlag
149     {
150         CRST_NO_LEVEL_CHECK = 1,
151         CRST_LEVEL_CHECK = 0,
152     };
153 #endif
154
155 private:
156     // Some Crsts have a "shutdown" mode. 
157     // A Crst in shutdown mode can only be taken / released by special 
158     // (the helper / finalizer / shutdown) threads. Any other thread that tries to take
159     // the a "shutdown" crst will immediately release the Crst and instead just block forever.
160     //
161     // This prevents random threads from blocking the special threads from doing finalization on shutdown. 
162     // 
163     // Unfortunately, each Crst needs its own "shutdown" flag because we can't convert all the locks
164     // into shutdown locks at once. For eg, the TSL needs to suspend the runtime before
165     // converting to a shutdown lock. But it can't suspend the runtime while holding 
166     // a UNSAFE_ANYMODE lock (such as the debugger-lock). So at least the debugger-lock
167     // and TSL need to be set separately.
168     // 
169     // So for such Crsts, it's the caller's responsibility to detect if the crst is in
170     // shutdown mode, and if so, call this function after enter.
171     void ReleaseAndBlockForShutdownIfNotSpecialThread();
172
173     // Enter & Leave are deliberately private to force callers to use the
174     // Holder class.  If you bypass the Holder class and access these members
175     // directly, your lock is not exception-safe.
176     //
177     // noLevelCheckFlag parameter lets you disable the crst level checking. This is
178     // very dangerous so it is only used when the constructor is the one performing
179     // the Enter (that attempt cannot possibly block since the current thread is
180     // the only one with a pointer to the crst.)
181     //
182     // For obvious reasons, this parameter must never be made public.
183     void Enter(INDEBUG(NoLevelCheckFlag noLevelCheckFlag = CRST_LEVEL_CHECK));
184     void Leave();
185
186     void SpinEnter();
187
188 #ifndef DACCESS_COMPILE
189     DEBUG_NOINLINE static void AcquireLock(CrstBase *c) PUB {
190         WRAPPER_NO_CONTRACT;
191         ANNOTATION_SPECIAL_HOLDER_CALLER_NEEDS_DYNAMIC_CONTRACT;
192         c->Enter(); 
193     }
194
195     DEBUG_NOINLINE static void ReleaseLock(CrstBase *c) PUB { 
196         WRAPPER_NO_CONTRACT;
197         ANNOTATION_SPECIAL_HOLDER_CALLER_NEEDS_DYNAMIC_CONTRACT;
198         c->Leave(); 
199     }
200
201 #else // DACCESS_COMPILE
202
203     // in DAC builds, we don't actually acquire the lock, we just determine whether the LS
204     // already holds it. If so, we assume the data is inconsistent and throw an exception. 
205     // Argument: 
206     //     input: c - the lock to be checked. 
207     // Note: Throws
208     static void AcquireLock(CrstBase * c) PUB
209     { 
210         SUPPORTS_DAC;
211         if (c->GetEnterCount() != 0) 
212         {
213             ThrowHR(CORDBG_E_PROCESS_NOT_SYNCHRONIZED); 
214         }
215     };
216
217     static void ReleaseLock(CrstBase *c) PUB
218     { 
219         SUPPORTS_DAC;
220     };
221 #endif // DACCESS_COMPILE
222
223 public:
224     //-----------------------------------------------------------------
225     // Clean up critical section
226     // Safe to call multiple times or on non-initialized critical section
227     //-----------------------------------------------------------------
228     void Destroy();
229
230 #ifdef _DEBUG
231     //-----------------------------------------------------------------
232     // Check if attempting to take the lock would violate level order.
233     //-----------------------------------------------------------------
234     BOOL IsSafeToTake();
235     // Checks that the lock can be taken
236     BOOL Debug_CanTake()
237     {
238         WRAPPER_NO_CONTRACT;
239         // Actually take the lock and release it immediatelly, that will do all the necessary checks
240         Enter();
241         Leave();
242         return TRUE;
243     }
244     void SetCantLeave(BOOL bSet)
245     {
246         LIMITED_METHOD_CONTRACT;
247         if (bSet)
248             FastInterlockIncrement(&m_cannotLeave);
249         else
250         {
251             _ASSERTE(m_cannotLeave);
252             FastInterlockDecrement(&m_cannotLeave);
253         }
254     };    
255     //-----------------------------------------------------------------
256     // Is the current thread the owner?
257     //-----------------------------------------------------------------
258     BOOL OwnedByCurrentThread()
259     {
260         WRAPPER_NO_CONTRACT;
261 #ifdef CROSSGEN_COMPILE
262         return TRUE;
263 #else
264         return m_holderthreadid.IsSameThread();
265 #endif
266     }
267     
268     CrstBase *GetThreadsOwnedCrsts();
269     void SetThreadsOwnedCrsts(CrstBase *pCrst);
270
271     __declspec(noinline) EEThreadId GetHolderThreadId()
272     {
273         LIMITED_METHOD_CONTRACT;
274         return m_holderthreadid;
275     }
276
277 #endif //_DEBUG
278     
279     //-----------------------------------------------------------------
280     // For clients who want to assert whether they are in or out of the
281     // region.
282     //-----------------------------------------------------------------
283     UINT GetEnterCount()
284     {
285         LIMITED_METHOD_DAC_CONTRACT;
286 #ifdef _DEBUG
287         return m_entercount;
288 #else
289         return 0;
290 #endif //_DEBUG
291     }
292
293 protected:    
294
295     VOID InitWorker(INDEBUG_COMMA(CrstType crstType) CrstFlags flags);
296
297 #ifdef _DEBUG
298     void DebugInit(CrstType crstType, CrstFlags flags);
299     void DebugDestroy();
300 #endif
301
302 #endif // CLR_STANDALONE_BINDER
303
304     union {
305         CRITICAL_SECTION    m_criticalsection;
306 #ifdef FEATURE_INCLUDE_ALL_INTERFACES
307         IHostCrst          *m_pHostCrst;
308 #endif // FEATURE_INCLUDE_ALL_INTERFACES
309     };
310
311     typedef enum
312     {
313         // Mask to indicate reserved flags
314         CRST_RESERVED_FLAGS_MASK = 0xC0000000,
315         // private flag to indicate initialized Crsts
316         CRST_INITIALIZED = 0x80000000,
317         // private flag to indicate Crst is OS Critical Section
318         CRST_OS_CRIT_SEC = 0x40000000,
319         // rest of the flags are CrstFlags
320     } CrstReservedFlags;
321     DWORD               m_dwFlags;            // Re-entrancy and same level
322 #ifdef _DEBUG
323     UINT                m_entercount;       // # of unmatched Enters.
324     CrstType            m_crstType;         // Type enum (should have a descriptive name for debugging)
325     const char         *m_tag;              // Stringized form of the tag for easy debugging
326     int                 m_crstlevel;        // what level is the crst in?
327     EEThreadId          m_holderthreadid;   // current holder (or NULL)
328     CrstBase           *m_next;             // link for global linked list
329     CrstBase           *m_prev;             // link for global linked list
330     Volatile<LONG>      m_cannotLeave; 
331
332     // Check for dead lock situation.
333     ULONG               m_countNoTriggerGC;
334     
335     void                PostEnter ();
336     void                PreEnter ();
337     void                PreLeave  ();
338 #endif //_DEBUG
339     
340 #ifndef CLR_STANDALONE_BINDER
341     
342 private:
343
344     void SetOSCritSec ()
345     {
346         m_dwFlags |= CRST_OS_CRIT_SEC;
347     }
348     void ResetOSCritSec ()
349     {
350         m_dwFlags &= ~CRST_OS_CRIT_SEC;
351     }
352     BOOL IsOSCritSec ()
353     {
354         return m_dwFlags & CRST_OS_CRIT_SEC;
355     }
356     void SetCrstInitialized()
357     {
358         m_dwFlags |= CRST_INITIALIZED;
359     }
360
361     BOOL IsCrstInitialized()
362     {
363         return m_dwFlags & CRST_INITIALIZED;
364     }
365
366     BOOL CanBeTakenDuringShutdown()
367     {
368         return m_dwFlags & CRST_TAKEN_DURING_SHUTDOWN;
369     }
370
371     void SetFlags(CrstFlags f)
372     {
373         WRAPPER_NO_CONTRACT;
374         _ASSERTE(((CrstFlags)(f & ~CRST_RESERVED_FLAGS_MASK)) == f);
375         m_dwFlags = (f & ~CRST_RESERVED_FLAGS_MASK) | (m_dwFlags & CRST_RESERVED_FLAGS_MASK);
376     }
377
378     void ResetFlags() // resets the reserved and the CrstFlags
379     {
380         m_dwFlags = 0;
381     }
382     // ------------------------------- Holders ------------------------------
383  public:
384      //
385      // CrstHolder is optimized for the common use that takes the lock in constructor 
386      // and releases it in destructor. Users that require all Holder features
387      // can use CrstHolderWithState.
388      //
389     class CrstHolder
390     {
391         CrstBase * m_pCrst;
392
393     public:
394         inline CrstHolder(CrstBase * pCrst)
395             : m_pCrst(pCrst)
396         {
397             WRAPPER_NO_CONTRACT;
398             AcquireLock(pCrst);
399         }
400
401         inline ~CrstHolder()
402         {
403             WRAPPER_NO_CONTRACT;
404
405             VALIDATE_HOLDER_STACK_CONSUMPTION_FOR_TYPE(HSV_ValidateMinimumStackReq);
406             ReleaseLock(m_pCrst);
407         }
408     };
409
410     // Note that the holders for CRSTs are used in extremely low stack conditions. Because of this, they 
411     // aren't allowed to use more than HOLDER_CODE_MINIMUM_STACK_LIMIT pages of stack.
412     typedef DacHolder<CrstBase *, CrstBase::AcquireLock, CrstBase::ReleaseLock, 0, CompareDefault, HSV_ValidateMinimumStackReq> CrstHolderWithState;
413
414     // We have some situations where we're already holding a lock, and we need to release and reacquire the lock across a window.
415     // This is a dangerous construct because the backout code can block.
416     // Generally, it's better to use a regular CrstHolder, and then use the Release() / Acquire() methods on it.
417     // This just exists to convert legacy OS Critical Section patterns over to holders.
418     typedef DacHolder<CrstBase *, CrstBase::ReleaseLock, CrstBase::AcquireLock, 0, CompareDefault, HSV_ValidateMinimumStackReq> UnsafeCrstInverseHolder;
419
420 #endif // CLR_STANDALONE_BINDER
421 };
422
423 #ifndef CLR_STANDALONE_BINDER
424 typedef CrstBase::CrstHolder CrstHolder;
425 typedef CrstBase::CrstHolderWithState CrstHolderWithState;
426 #endif // CLR_STANDALONE_BINDER
427
428
429 // The CRST.
430 class Crst : public CrstBase
431 {
432 #ifndef CLR_STANDALONE_BINDER
433 public:
434     void *operator new(size_t size)
435     {
436         WRAPPER_NO_CONTRACT;
437         return new BYTE[size];
438     }
439
440 private:
441     // Do not use inplace operator new on Crst. A wrong destructor would be called if the constructor fails.
442     // Use CrstStatic or CrstExplicitInit instead of the inplace operator new.
443     void *operator new(size_t size, void *pInPlace);
444
445 public:
446
447 #ifndef DACCESS_COMPILE
448
449     //-----------------------------------------------------------------
450     // Constructor.
451     //-----------------------------------------------------------------
452     Crst(CrstType crstType, CrstFlags flags = CRST_DEFAULT)
453     {
454         WRAPPER_NO_CONTRACT;
455
456         // throw away the debug-only parameter in retail
457         InitWorker(INDEBUG_COMMA(crstType) flags);
458     }
459
460     //-----------------------------------------------------------------
461     // Destructor.
462     //-----------------------------------------------------------------
463     ~Crst()
464     {
465         WRAPPER_NO_CONTRACT;
466
467         Destroy();
468     };
469
470 #else
471
472     Crst(CrstType crstType, CrstFlags flags = CRST_DEFAULT) {
473         LIMITED_METHOD_CONTRACT;
474     };
475
476 #endif
477
478     Crst() {
479         LIMITED_METHOD_CONTRACT;
480     }
481
482 #endif // CLR_STANDALONE_BINDER
483 };
484
485 typedef DPTR(Crst) PTR_Crst;
486
487 /* to be used as static variable - no constructor/destructor, assumes zero 
488    initialized memory */
489 class CrstStatic : public CrstBase
490 {
491 #ifndef CLR_STANDALONE_BINDER
492 public:
493     VOID Init(CrstType crstType, CrstFlags flags = CRST_DEFAULT)
494     {
495         WRAPPER_NO_CONTRACT;
496
497         _ASSERTE((flags & CRST_INITIALIZED) == 0);
498
499         // throw away the debug-only parameter in retail
500         InitWorker(INDEBUG_COMMA(crstType) flags);
501     }
502
503     bool InitNoThrow(CrstType crstType, CrstFlags flags = CRST_DEFAULT)
504     {
505         CONTRACTL {
506             NOTHROW;
507         } CONTRACTL_END;    
508
509         _ASSERTE((flags & CRST_INITIALIZED) == 0);
510
511         bool fSuccess = false;
512
513         EX_TRY
514         {
515             // throw away the debug-only parameter in retail
516             InitWorker(INDEBUG_COMMA(crstType) flags);
517             fSuccess = true;
518         }
519         EX_CATCH
520         {
521         }
522         EX_END_CATCH(SwallowAllExceptions)
523
524         return fSuccess;
525     }
526 #endif // CLR_STANDALONE_BINDER
527 };
528
529 /* to be used as regular variable when a explicit call to Init method is needed */
530 class CrstExplicitInit : public CrstStatic
531 {
532 #ifndef CLR_STANDALONE_BINDER
533 public:
534     CrstExplicitInit() {
535         m_dwFlags = 0;
536     }
537      ~CrstExplicitInit() {
538 #ifndef DACCESS_COMPILE
539         Destroy();
540 #endif
541     }   
542 #endif // CLR_STANDALONE_BINDER
543 };
544
545 #ifndef CLR_STANDALONE_BINDER
546 __inline BOOL IsOwnerOfCrst(LPVOID lock)
547 {
548     WRAPPER_NO_CONTRACT;
549
550 #ifdef _DEBUG
551     return ((Crst*)lock)->OwnedByCurrentThread();
552 #else
553     // This function should not be called on free build.
554     DebugBreak();
555     return TRUE;
556 #endif
557 }
558
559 #endif // CLR_STANDALONE_BINDER
560
561 #ifdef TEST_DATA_CONSISTENCY
562 // used for test purposes. Determines if a crst is held. 
563 void DebugTryCrst(CrstBase * pLock);
564 #endif
565 #endif // __crst_h__
566
567