Skip to content

Instantly share code, notes, and snippets.

@MartinNowak
Last active August 29, 2015 14:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MartinNowak/5111611ddc476eb49298 to your computer and use it in GitHub Desktop.
Save MartinNowak/5111611ddc476eb49298 to your computer and use it in GitHub Desktop.
atomic fetch_add
import core.memory;
version (X86_64)
{
T atomicOp(string op : "+=", T)(ref shared T val, T mod) pure nothrow @nogc
if (__traits(isIntegral, T))
{
T oval = void;
static if (T.sizeof == 1)
{
asm pure nothrow @nogc
{
mov AL, mod;
mov RDX, val;
lock;
xadd[RDX], AL;
mov oval, AL;
}
}
else static if (T.sizeof == 2)
{
asm pure nothrow @nogc
{
mov AX, mod;
mov RDX, val;
lock;
xadd[RDX], AX;
mov oval, AX;
}
}
else static if (T.sizeof == 4)
{
asm pure nothrow @nogc
{
mov EAX, mod;
mov RDX, val;
lock;
xadd[RDX], EAX;
mov oval, EAX;
}
}
else static if (T.sizeof == 8)
{
asm pure nothrow @nogc
{
mov RAX, mod;
mov RDX, val;
lock;
xadd[RDX], RAX;
mov oval, RAX;
}
}
oval += mod;
return oval;
}
}
unittest
{
shared ubyte u8 = 1;
shared ushort u16 = 2;
shared uint u32 = 3;
shared ulong u64 = 4;
shared byte i8 = 5;
shared short i16 = 6;
shared int i32 = 7;
shared long i64 = 8;
assert(atomicOp!"+="(u8, 8) == 9);
assert(atomicOp!"+="(u16, 8) == 10);
assert(atomicOp!"+="(u32, 8) == 11);
assert(atomicOp!"+="(u64, 8) == 12);
assert(atomicOp!"+="(i8, 8) == 13);
assert(atomicOp!"+="(i16, 8) == 14);
assert(atomicOp!"+="(i32, 8) == 15);
assert(atomicOp!"+="(i64, 8) == 16);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment