145
|
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
|
|
20 extern (C) void _d_critical_init()
|
|
21 {
|
|
22 initMutex(cast(Mutex*)&gcs.mtx);
|
|
23 head = &gcs;
|
|
24 }
|
|
25
|
|
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
|
|
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
|
|
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
|
|
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 }
|