Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions d/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/bin
50 changes: 50 additions & 0 deletions d/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
DMD=bin/dmd2/linux/bin64/dmd
DMD_VERSION=2.074.0
LDC=bin/ldc2-$(LDC_VERSION)-linux-$(PLATFORM)/bin/ldc2
LDC_VERSION=1.3.0
DFLAGS=-g
PLATFORM=x86_64

all: bin/serial_opt bin/async_opt bin/async_queue_opt bin/async_atomic_opt

################################################################################
# Auto-bootstrap DMD & LDC for outdated Debian/Ubuntu
################################################################################

bin:
mkdir -p $@

bin/dmd2: | bin
curl -fSL --retry 3 "http://downloads.dlang.org/releases/2.x/$(DMD_VERSION)/dmd.$(DMD_VERSION).linux.tar.xz" | tar -Jxf - -C $|
bin/dmd2/linux/bin64/dmd: | bin/dmd2

bin/ldc2-$(LDC_VERSION)-linux-$(PLATFORM): | bin
curl -fSL --retry 3 "https://github.com/ldc-developers/ldc/releases/download/v$(LDC_VERSION)/ldc2-$(LDC_VERSION)-linux-$(PLATFORM).tar.xz" \
| tar -Jxf - -C $|

bin/ldc2-$(LDC_VERSION)-linux-$(PLATFORM)/bin/ldc2: | bin/ldc2-$(LDC_VERSION)-linux-$(PLATFORM)

bin/%_opt: %.d $(LDC) | bin
$(LDC) -g -O4 -mcpu=native -release $(DFLAGS) $< -of$@

bin/%: %.d $(DMD) | bin
$(DMD) $(DFLAGS) $< -of$@

################################################################################
# Programs
################################################################################

BENCHMARK=../async-io/benchmark.sh
TEST=../async-io/test.sh

benchmark: bin/serial_opt bin/async_opt
$(BENCHMARK) $< $(word 2, $^)

benchmark_queue: bin/serial_opt bin/async_queue_opt
$(BENCHMARK) $< $(word 2, $^)

benchmark_atomic: bin/serial_opt bin/async_atomic_opt
$(BENCHMARK) $< $(word 2, $^)

test: bin/async_opt
$(TEST) $<
6 changes: 6 additions & 0 deletions d/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

Async implementations:

- `async.d` -> Out of the box [`std.concurrency`](https://dlang.org/phobos/std_concurrency.html)
- `async_queue.d` -> Locking queue
- `async_atomic.d` -> Atomic version (cheated)
26 changes: 26 additions & 0 deletions d/async.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env rdmd

__gshared int maxInt;
__gshared int currentInt;

void main(string[] args)
{
import std.conv, std.stdio;
import std.concurrency;
auto pid = spawn({
for (;;)
{
if (receiveOnly!bool)
printf("%d", currentInt++);
else
goto end;
}
end:
});
auto n = args[1].to!int;
pid.setMaxMailboxSize(n + 10, OnCrowding.ignore);
foreach (i; 0..n)
pid.send(true);

pid.send(false);
}
49 changes: 49 additions & 0 deletions d/async_atomic.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env rdmd

__gshared int currentInt;

enum States {
pending,
printInt,
exit
}
shared States state;

import core.sync.mutex;

void main(string[] args)
{
import std.conv, std.stdio;
import std.concurrency;
import core.atomic;
auto pid = spawn({
with (States)
for_label: for (;;) {
final switch (state.atomicLoad) {
case printInt:
currentInt.write;
state.atomicStore(States.pending);
goto for_label;
case pending:
goto for_label;
case exit:
goto end;
}
}
end:
});
auto n = args[1].to!int;
foreach (i; 0..n)
{
state.atomicStore(States.printInt);
for (;;) {
if (state.atomicLoad != States.printInt) {
currentInt++;
goto end;
}
}
end:
}

state.atomicStore(States.exit);
}
67 changes: 67 additions & 0 deletions d/async_queue.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env dub
/+dub.sdl:
name "async_queue"
dependency "emsi_containers" version="~>0.5.3"
+/

import core.sync.mutex : Mutex;

// this isn't faster than Mutex
class SpinLock : Object.Monitor
{
import core.atomic, core.thread;
void lock() { while (!cas(&locked, false, true)) { Thread.yield(); } }
void unlock() { atomicStore!(MemoryOrder.rel)(locked, false); }
shared bool locked;
}

void main(string[] args)
//@nogc
{
import std.conv, std.stdio;
import std.concurrency;
import core.memory;
GC.disable();

auto n = args[1].to!int;

import std.experimental.allocator : make;
import std.experimental.allocator.mallocator: Mallocator;
alias alloc = Mallocator.instance;

__gshared Mutex mutex;
//__gshared SpinLock mutex;
mutex = alloc.make!(typeof(mutex));

import std.container.dlist;
//__gshared DList!(void function() @safe) queue;
__gshared DList!int queue;

__gshared bool done;
scope(exit) done = true;

auto pid = spawn({
typeof(queue) localQueue;
for (;;) {
synchronized(mutex) {
if (!queue.empty) {
localQueue = queue;
queue = typeof(queue).init;
}
}

foreach (e; localQueue[])
"%d".printf(e);
//e();

if (done)
goto end;
}
end:
});

foreach (i; 0..n)
synchronized(mutex)
queue ~= i;
//queue ~= { 0.write; };
}
8 changes: 8 additions & 0 deletions d/serial.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env rdmd

void main(string[] args)
{
import std.conv, std.stdio;
foreach (i; 0..args[1].to!int)
"%d".printf(i);
}