Skip to content

Commit

Permalink
Back to atomicOp since atomicFetchAdd/Sub has been added only recently
Browse files Browse the repository at this point in the history
even on dmd there was a little copy/paste error where atomicFetchAdd
was calling atomicFetchSub...
Has been fixed in dlang/druntime#3342 but that is
very recent.
  • Loading branch information
skoppe committed Jun 2, 2021
1 parent 2dfece0 commit 1c1b345
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 26 deletions.
40 changes: 22 additions & 18 deletions source/concurrency/bitfield.d
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
module concurrency.bitfield;

import core.atomic : atomicFetchSub, atomicLoad, MemoryOrder;
import core.atomic : atomicOp, atomicLoad, MemoryOrder;

struct Guard(Flags) {
private SharedBitField!(Flags)* obj;
size_t oldState, newState;
~this() {
release();
}
void release(size_t sub = 0) {
if (obj !is null) {
// TODO: want to use atomicFetchSub but (proper) support is only recent
// obj.store.atomicFetchSub!(MemoryOrder.rel)(sub | Flags.locked);
obj.store.atomicOp!"-="(sub | Flags.locked);
}
obj = null;
}
bool was(Flags flags) {
return (oldState & flags) == flags;
}
}

shared struct SharedBitField(Flags) {
static assert(__traits(compiles, Flags.locked), "Must has a non-zero 'locked' flag");
static assert(Flags.locked != 0, "Must has a non-zero 'locked' flag");
struct Guard {
private SharedBitField!(Flags)* obj;
size_t oldState, newState;
~this() {
release();
}
void release(size_t sub = 0) {
if (obj !is null)
obj.store.atomicFetchSub!(MemoryOrder.rel)(sub | Flags.locked);
obj = null;
}
bool was(Flags flags) {
return (oldState & flags) == flags;
}
}
private shared size_t store;
Guard lock(size_t or = 0, size_t add = 0, size_t sub = 0) return scope @safe @nogc nothrow {
return Guard(&this, update(Flags.locked | or, add, sub).expand);
Guard!Flags lock(size_t or = 0, size_t add = 0, size_t sub = 0) return scope @safe @nogc nothrow {
return Guard!Flags(&this, update(Flags.locked | or, add, sub).expand);
}
auto update(size_t or, size_t add = 0, size_t sub = 0) nothrow {
import concurrency.utils : spin_yield, casWeak;
Expand Down
30 changes: 22 additions & 8 deletions source/concurrency/stoptoken.d
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ private void spin_yield() nothrow @trusted @nogc {

private struct stop_state {
import core.thread : Thread;
import core.atomic : atomicStore, atomicLoad, MemoryOrder, atomicFetchSub, atomicFetchAdd;
import core.atomic : atomicStore, atomicLoad, MemoryOrder, atomicOp;

static if (__traits(compiles, () { import core.atomic : casWeak; }) && __traits(compiles, () {
import core.internal.atomic : atomicCompareExchangeWeakNoResult;
Expand All @@ -145,19 +145,27 @@ private struct stop_state {

public:
void add_token_reference() nothrow @safe @nogc {
state_.atomicFetchAdd!(MemoryOrder.raw)(token_ref_increment);
// TODO: want to use atomicFetchAdd but (proper) support is only recent
// state_.atomicFetchAdd!(MemoryOrder.raw)(token_ref_increment);
state_.atomicOp!"+="(token_ref_increment);
}

void remove_token_reference() nothrow @safe @nogc {
state_.atomicFetchSub!(MemoryOrder.acq_rel)(token_ref_increment);
// TODO: want to use atomicFetchSub but (proper) support is only recent
// state_.atomicFetchSub!(MemoryOrder.acq_rel)(token_ref_increment);
state_.atomicOp!"-="(token_ref_increment);
}

void add_source_reference() nothrow @safe @nogc {
state_.atomicFetchAdd!(MemoryOrder.raw)(source_ref_increment);
// TODO: want to use atomicFetchAdd but (proper) support is only recent
// state_.atomicFetchAdd!(MemoryOrder.raw)(source_ref_increment);
state_.atomicOp!"+="(source_ref_increment);
}

void remove_source_reference() nothrow @safe @nogc {
state_.atomicFetchSub!(MemoryOrder.acq_rel)(source_ref_increment);
// TODO: want to use atomicFetchSub but (proper) support is only recent
// state_.atomicFetchSub!(MemoryOrder.acq_rel)(source_ref_increment);
state_.atomicOp!"-="(source_ref_increment);
}

bool request_stop() nothrow @safe {
Expand Down Expand Up @@ -355,15 +363,21 @@ private:
}

void unlock() nothrow @safe @nogc {
state_.atomicFetchSub!(MemoryOrder.rel)(locked_flag);
// TODO: want to use atomicFetchSub but (proper) support is only recent
// state_.atomicFetchSub!(MemoryOrder.rel)(locked_flag);
state_.atomicOp!"-="(locked_flag);
}

void unlock_and_increment_token_ref_count() nothrow @safe @nogc {
state_.atomicFetchSub!(MemoryOrder.rel)(locked_flag - token_ref_increment);
// TODO: want to use atomicFetchSub but (proper) support is only recent
// state_.atomicFetchSub!(MemoryOrder.rel)(locked_flag - token_ref_increment);
state_.atomicOp!"-="(locked_flag - token_ref_increment);
}

void unlock_and_decrement_token_ref_count() nothrow @safe @nogc {
state_.atomicFetchSub!(MemoryOrder.acq_rel)(locked_flag + token_ref_increment);
// TODO: want to use atomicFetchSub but (proper) support is only recent
// state_.atomicFetchSub!(MemoryOrder.acq_rel)(locked_flag + token_ref_increment);
state_.atomicOp!"-="(locked_flag + token_ref_increment);
}

enum stop_requested_flag = 1L;
Expand Down

0 comments on commit 1c1b345

Please sign in to comment.