Skip to content

Commit

Permalink
Fix taggedPointer to work with pointer to qualified type (#40)
Browse files Browse the repository at this point in the history
* Add unittest for 'taggedPointer to shared data'

* Fix 'taggedPointer to shared data'
  • Loading branch information
thaven authored Feb 11, 2021
1 parent 801e332 commit 9c32c6f
Showing 1 changed file with 37 additions and 5 deletions.
42 changes: 37 additions & 5 deletions source/mir/bitmanip.d
Original file line number Diff line number Diff line change
Expand Up @@ -157,25 +157,33 @@ private ulong getBitsForAlign()(ulong a)

private template createReferenceAccessor(string store, T, ulong bits, string name)
{
enum storage = "private void* " ~ store ~ "_ptr;\n";
import std.traits : CopyTypeQualifiers, PointerTarget;

static if (is(T == class))
alias Q = T;
else
alias Q = PointerTarget!T;

enum storageType = (CopyTypeQualifiers!(Q, void)*).stringof;
enum storage = "private " ~ storageType ~ ' ' ~ store ~ "_ptr;\n";
enum storage_accessor = "@property ref size_t " ~ store ~ "()() return @trusted pure nothrow @nogc const { "
~ "return *cast(size_t*) &" ~ store ~ "_ptr;}\n"
~ "@property void " ~ store ~ "()(size_t v) @trusted pure nothrow @nogc { "
~ "" ~ store ~ "_ptr = cast(void*) v;}\n";
~ "" ~ store ~ "_ptr = cast(" ~ storageType ~ ") v;}\n";

enum mask = (1UL << bits) - 1;
enum maskInv = ~mask;
// getter
enum ref_accessor = "@property "~T.stringof~" "~name~"()() @trusted pure nothrow @nogc const { auto result = "
~ "("~store~" & "~ maskInv.stringof ~"); "
~ "return cast("~T.stringof~") cast(void*) result;}\n"
~ "return cast("~T.stringof~") cast(" ~ storageType ~ ") result;}\n"
// setter
~"@property void "~name~"()("~T.stringof~" v) @trusted pure nothrow @nogc { "
~"assert(((cast(typeof("~store~")) cast(void*) v) & "~ mask.stringof
~"assert(((cast(typeof("~store~")) cast(" ~ storageType ~ ") v) & "~ mask.stringof
~`) == 0, "Value not properly aligned for '`~name~`'"); `
~store~" = cast(typeof("~store~"))"
~" (("~store~" & (cast(typeof("~store~")) "~ mask.stringof ~"))"
~" | ((cast(typeof("~store~")) cast(void*) v) & (cast(typeof("~store~")) "~ maskInv.stringof ~")));}\n";
~" | ((cast(typeof("~store~")) cast(" ~ storageType ~ ") v) & (cast(typeof("~store~")) "~ maskInv.stringof ~")));}\n";

enum result = storage ~ storage_accessor ~ ref_accessor;
}
Expand Down Expand Up @@ -610,3 +618,27 @@ version(mir_core_test) unittest
catch (AssertError ae)
{ assert(ae.msg.canFind("Value is smaller than the minimum value of bitfield 'b'"), ae.msg); }
}

@system version(mir_core_test) unittest
{
import core.atomic : atomicStore, atomicLoad, MO = MemoryOrder;

static struct S
{
mixin(taggedPointer!(
shared(int)*, "si",
bool, "f", 1));

this(shared(int)* ptr, bool flag)
{
si = ptr;
f = flag;
}
}

shared static S s;
shared static int i;

s.atomicStore!(MO.raw)(S(&i, true));
assert(s.atomicLoad!(MO.raw) == S(&i, true));
}

0 comments on commit 9c32c6f

Please sign in to comment.