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