mirror of
https://review.haiku-os.org/buildtools
synced 2025-02-06 22:04:45 +01:00
92b3138b83
Updated dependencies: * GMP 6.2.1 * ISL 0.24 * MPL 1.2.1 * MPFR 4.1.0 The dependencies were pulled in by running the ./contrib/download_prerequisites script and then manually removing the symbolic links and archives, and renaming the directories (i.e mv isl-0.24 to isl)
91 lines
2.3 KiB
D
91 lines
2.3 KiB
D
/**
|
|
* Implementation of support routines for synchronized blocks.
|
|
*
|
|
* Copyright: Copyright Digital Mars 2000 - 2011.
|
|
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
|
* Authors: Walter Bright, Sean Kelly
|
|
* Source: $(DRUNTIMESRC rt/_critical_.d)
|
|
*/
|
|
|
|
/* Copyright Digital Mars 2000 - 2011.
|
|
* Distributed under the Boost Software License, Version 1.0.
|
|
* (See accompanying file LICENSE or copy at
|
|
* http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
module rt.critical_;
|
|
|
|
nothrow:
|
|
|
|
import rt.monitor_, core.atomic;
|
|
|
|
extern (C) void _d_critical_init() @nogc nothrow
|
|
{
|
|
initMutex(cast(Mutex*)&gcs.mtx);
|
|
head = &gcs;
|
|
}
|
|
|
|
extern (C) void _d_critical_term() @nogc nothrow
|
|
{
|
|
// This function is only ever called by the runtime shutdown code
|
|
// and therefore is single threaded so the following cast is fine.
|
|
auto h = cast()head;
|
|
for (auto p = h; p; p = p.next)
|
|
destroyMutex(cast(Mutex*)&p.mtx);
|
|
}
|
|
|
|
extern (C) void _d_criticalenter(D_CRITICAL_SECTION* cs)
|
|
{
|
|
assert(cs !is null);
|
|
ensureMutex(cast(shared(D_CRITICAL_SECTION*)) cs);
|
|
lockMutex(&cs.mtx);
|
|
}
|
|
|
|
extern (C) void _d_criticalenter2(D_CRITICAL_SECTION** pcs)
|
|
{
|
|
if (atomicLoad!(MemoryOrder.acq)(*cast(shared) pcs) is null)
|
|
{
|
|
lockMutex(cast(Mutex*)&gcs.mtx);
|
|
if (atomicLoad!(MemoryOrder.raw)(*cast(shared) pcs) is null)
|
|
{
|
|
auto cs = new shared D_CRITICAL_SECTION;
|
|
initMutex(cast(Mutex*)&cs.mtx);
|
|
atomicStore!(MemoryOrder.rel)(*cast(shared) pcs, cs);
|
|
}
|
|
unlockMutex(cast(Mutex*)&gcs.mtx);
|
|
}
|
|
lockMutex(&(*pcs).mtx);
|
|
}
|
|
|
|
extern (C) void _d_criticalexit(D_CRITICAL_SECTION* cs)
|
|
{
|
|
assert(cs !is null);
|
|
unlockMutex(&cs.mtx);
|
|
}
|
|
|
|
private:
|
|
|
|
shared D_CRITICAL_SECTION* head;
|
|
shared D_CRITICAL_SECTION gcs;
|
|
|
|
struct D_CRITICAL_SECTION
|
|
{
|
|
D_CRITICAL_SECTION* next;
|
|
Mutex mtx;
|
|
}
|
|
|
|
void ensureMutex(shared(D_CRITICAL_SECTION)* cs)
|
|
{
|
|
if (atomicLoad!(MemoryOrder.acq)(cs.next) is null)
|
|
{
|
|
lockMutex(cast(Mutex*)&gcs.mtx);
|
|
if (atomicLoad!(MemoryOrder.raw)(cs.next) is null)
|
|
{
|
|
initMutex(cast(Mutex*)&cs.mtx);
|
|
auto ohead = head;
|
|
head = cs;
|
|
atomicStore!(MemoryOrder.rel)(cs.next, ohead);
|
|
}
|
|
unlockMutex(cast(Mutex*)&gcs.mtx);
|
|
}
|
|
}
|