mirror of
https://github.com/openRuyi-Project/gcc.git
synced 2026-06-14 23:45:53 +00:00
f204359931
D front-end changes: - Import latest changes from dmd v2.107.0-beta.1. - Keywords like `__FILE__' are now always evaluated at the callsite. D runtime changes: - Import latest changes from druntime v2.107.0-beta.1. - Added `nameSig' field to TypeInfo_Class in object.d. Phobos changes: - Import latest changes from phobos v2.107.0-beta.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd bce5c1f7b5. * d-attribs.cc (build_attributes): Update for new front-end interface. * d-lang.cc (d_parse_file): Likewise. * decl.cc (DeclVisitor::visit (VarDeclaration *)): Likewise. * expr.cc (build_lambda_tree): New function. (ExprVisitor::visit (FuncExp *)): Use build_lambda_tree. (ExprVisitor::visit (SymOffExp *)): Likewise. (ExprVisitor::visit (VarExp *)): Likewise. * typeinfo.cc (create_tinfo_types): Add two ulong fields to internal TypeInfo representation. (TypeInfoVisitor::visit (TypeInfoClassDeclaration *)): Emit stub data for TypeInfo_Class.nameSig. (TypeInfoVisitor::visit (TypeInfoStructDeclaration *)): Update for new front-end interface. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime bce5c1f7b5. * src/MERGE: Merge upstream phobos e4d0dd513.
89 lines
1.9 KiB
D
89 lines
1.9 KiB
D
/**
|
|
* SpinLock for runtime internal usage.
|
|
*
|
|
* Copyright: Copyright Digital Mars 2015 -.
|
|
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
|
* Authors: Martin Nowak
|
|
* Source: $(DRUNTIMESRC core/internal/_spinlock.d)
|
|
*/
|
|
module core.internal.spinlock;
|
|
|
|
import core.atomic, core.thread;
|
|
|
|
shared struct SpinLock
|
|
{
|
|
/// for how long is the lock usually contended
|
|
enum Contention : ubyte
|
|
{
|
|
brief,
|
|
medium,
|
|
lengthy,
|
|
}
|
|
|
|
@trusted @nogc nothrow:
|
|
this(Contention contention)
|
|
{
|
|
this.contention = contention;
|
|
}
|
|
|
|
void lock()
|
|
{
|
|
if (cas(&val, size_t(0), size_t(1)))
|
|
return;
|
|
// Try to reduce the chance of another cas failure
|
|
// TTAS lock (https://en.wikipedia.org/wiki/Test_and_test-and-set)
|
|
immutable step = 1 << contention;
|
|
while (true)
|
|
{
|
|
for (size_t n; atomicLoad!(MemoryOrder.raw)(val); n += step)
|
|
yield(n);
|
|
if (cas(&val, size_t(0), size_t(1)))
|
|
return;
|
|
}
|
|
}
|
|
|
|
void unlock()
|
|
{
|
|
atomicStore!(MemoryOrder.rel)(val, size_t(0));
|
|
}
|
|
|
|
/// yield with backoff
|
|
void yield(size_t k)
|
|
{
|
|
import core.time;
|
|
if (k < pauseThresh)
|
|
return core.atomic.pause();
|
|
else // if (k < 32)
|
|
return Thread.yield();
|
|
// Thread.sleep(1.msecs);
|
|
}
|
|
|
|
private:
|
|
version (D_InlineAsm_X86)
|
|
enum X86 = true;
|
|
else version (D_InlineAsm_X86_64)
|
|
enum X86 = true;
|
|
else
|
|
enum X86 = false;
|
|
|
|
static if (X86)
|
|
enum pauseThresh = 16;
|
|
else
|
|
enum pauseThresh = 4;
|
|
|
|
size_t val;
|
|
Contention contention;
|
|
}
|
|
|
|
// aligned to cacheline to avoid false sharing
|
|
shared align(64) struct AlignedSpinLock
|
|
{
|
|
this(SpinLock.Contention contention) @trusted @nogc nothrow
|
|
{
|
|
impl = shared(SpinLock)(contention);
|
|
}
|
|
|
|
SpinLock impl;
|
|
alias impl this;
|
|
}
|