1 /**
2  * Implementation of support routines for synchronized blocks.
3  *
4  * Copyright: Copyright Digital Mars 2000 - 2011.
5  * License:   $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  * Authors:   Walter Bright, Sean Kelly
7  */
8 
9 /*          Copyright Digital Mars 2000 - 2011.
10  * Distributed under the Boost Software License, Version 1.0.
11  *    (See accompanying file LICENSE or copy at
12  *          http://www.boost.org/LICENSE_1_0.txt)
13  */
14 module rt.critical_;
15 
16 nothrow:
17 
18 import rt.monitor_, core.atomic;
19 
_d_critical_init()20 extern (C) void _d_critical_init()
21 {
22     initMutex(cast(Mutex*)&gcs.mtx);
23     head = &gcs;
24 }
25 
_d_critical_term()26 extern (C) void _d_critical_term()
27 {
28     for (auto p = head; p; p = p.next)
29         destroyMutex(cast(Mutex*)&p.mtx);
30 }
31 
_d_criticalenter(D_CRITICAL_SECTION * cs)32 extern (C) void _d_criticalenter(D_CRITICAL_SECTION* cs)
33 {
34     ensureMutex(cast(shared(D_CRITICAL_SECTION*)) cs);
35     lockMutex(&cs.mtx);
36 }
37 
_d_criticalexit(D_CRITICAL_SECTION * cs)38 extern (C) void _d_criticalexit(D_CRITICAL_SECTION* cs)
39 {
40     unlockMutex(&cs.mtx);
41 }
42 
43 private:
44 
45 shared D_CRITICAL_SECTION* head;
46 shared D_CRITICAL_SECTION gcs;
47 
48 struct D_CRITICAL_SECTION
49 {
50     D_CRITICAL_SECTION* next;
51     Mutex mtx;
52 }
53 
ensureMutex(shared (D_CRITICAL_SECTION)* cs)54 void ensureMutex(shared(D_CRITICAL_SECTION)* cs)
55 {
56     if (atomicLoad!(MemoryOrder.acq)(cs.next) is null)
57     {
58         lockMutex(cast(Mutex*)&gcs.mtx);
59         if (atomicLoad!(MemoryOrder.raw)(cs.next) is null)
60         {
61             initMutex(cast(Mutex*)&cs.mtx);
62             auto ohead = head;
63             head = cs;
64             atomicStore!(MemoryOrder.rel)(cs.next, ohead);
65         }
66         unlockMutex(cast(Mutex*)&gcs.mtx);
67     }
68 }
69