gcc/libphobos/libdruntime/rt/critical_.d
Iain Buclaw 92dd3e71f9 libphobos: Synchronize libdruntime bindings with upstream druntime
Reviewed-on: https://github.com/dlang/druntime/pull/3348

gcc/d/ChangeLog:

	* typeinfo.cc (TypeInfoVisitor::visit (TypeInfoDeclaration *)): Don't
	layout m_arg1 and m_arg2 fields.

libphobos/ChangeLog:

	* Makefile.in: Regenerate.
	* configure: Regenerate.
	* libdruntime/MERGE: Merge upstream druntime e4aae28e.
	* libdruntime/Makefile.am (DRUNTIME_DSOURCES): Refresh module list.
	(DRUNTIME_DSOURCES_BIONIC): Add core/sys/bionic/err.d.
	(DRUNTIME_DSOURCES_DARWIN): Add core/sys/darwin/err.d,
	core/sys/darwin/ifaddrs.d, core/sys/darwin/mach/nlist.d,
	core/sys/darwin/mach/stab.d, and core/sys/darwin/sys/attr.d.
	(DRUNTIME_DSOURCES_DRAGONFLYBSD): Add core/sys/dragonflybsd/err.d.
	(DRUNTIME_DSOURCES_FREEBSD): Add core/sys/freebsd/err.d.
	(DRUNTIME_DSOURCES_LINUX): Add core/sys/linux/err.d.
	(DRUNTIME_DSOURCES_NETBSD): Add core/sys/netbsd/err.d.
	(DRUNTIME_DSOURCES_OPENBSD): Add core/sys/openbsd/err.d.
	(DRUNTIME_DSOURCES_POSIX): Add core/sys/posix/locale.d,
	core/sys/posix/stdc/time.d, core/sys/posix/string.d, and
	core/sys/posix/strings.d.
	(DRUNTIME_DSOURCES_SOLARIS): Add core/sys/solaris/err.d.
	(DRUNTIME_DSOURCES_WINDOWS): Add core/sys/windows/sdkddkver.d,
	and core/sys/windows/stdc/time.d
	* libdruntime/Makefile.in: Regenerate.
	* libdruntime/gcc/sections/elf_shared.d (sizeofTLS): New function.
	* testsuite/libphobos.thread/fiber_guard_page.d: Use
	__traits(getMember) to get internal fields.
2021-01-30 16:50:57 +01:00

90 lines
2.2 KiB
D

/**
* Implementation of support routines for synchronized blocks.
*
* Copyright: Copyright Digital Mars 2000 - 2011.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Walter Bright, Sean Kelly
*/
/* 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()
{
initMutex(cast(Mutex*)&gcs.mtx);
head = &gcs;
}
extern (C) void _d_critical_term()
{
// 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);
}
}