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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Photon is a minimalistic multi-threaded fiber scheduler and event loop that works transparently with traditional blocking I/O C/C++/D/Rust libraries w/o degrading performance. For example one can run multituide of downloads with `std.net.curl` with fibers, no blocking - it is as fast as threads but using less resources. Think of it as Golang style concurrency that is brought to D transparently.

Just like its particle cousing, Photon’s nature is dual, seeking to unify 2 different concepts (such as async and blocking I/O) in many ways:
Fibers and Threads can be mixed and matched in coherent way.
Fibers and Threads can be mixed and matched in coherent way.
LibC syscall wrapper is overriden to be aware of D fiber scheduling and transparently uses the same eventloop if called on fiber and is passed through otherwise.

Explicit async model with tasks/futures could be integrated with pseudoblocking fiber scheduling,
Expand Down
8 changes: 4 additions & 4 deletions bench/harness/http_load.d
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ long fromMetric(string num) {
return mult * num.to!long;
}

int main(string[] argv) {
int main(string[] argv) {
bool trace = false;
getopt(argv,
"v", &trace
Expand Down Expand Up @@ -62,8 +62,8 @@ int main(string[] argv) {
writefln("time,concurrency,RPS(min),RPS(avg),RPS(max),errors(max),lat(75%%),lat(99%%)");
for(long c = start; c <= stop; c += step) {
c = c / step * step; // truncate to step
if (c < numThreads) c = numThreads;
auto dt = Clock.currTime();
if (c < numThreads) c = numThreads;
auto dt = Clock.currTime();
double[] rps = new double[runs];
double[] perc75 = new double[runs];
double[] perc99 = new double[runs];
Expand Down Expand Up @@ -102,7 +102,7 @@ int main(string[] argv) {
}
}
writefln("%s,%d,%f,%f,%f,%d,%f,%f",
dt.toISOExtString, c, reduce!(min)(rps), mean(rps), reduce!max(rps),
dt.toISOExtString, c, reduce!(min)(rps), mean(rps), reduce!max(rps),
reduce!max(errors), mean(perc75), mean(perc99));
stdout.flush();
Thread.sleep(100.msecs);
Expand Down
4 changes: 2 additions & 2 deletions bench/harness/rusage.d
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ int main(string[] argv) {
auto delta = stats.delta(prev);
prev = stats;
SysTime dt = Clock.currTime;
log.writefln("%s,%s,%f,%f,%f,%f,%f",
log.writefln("%s,%s,%f,%f,%f,%f,%f",
dt.toISOExtString, stats.name,
delta.rbytes / MB,
delta.wbytes / MB,
delta.stime / tickSize,
delta.utime / tickSize,
delta.utime / tickSize,
delta.rss * pageSize / MB
);
}
Expand Down
2 changes: 1 addition & 1 deletion bench/static_http/hello.d
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class HelloWorldProcessor : HttpProcessor {
HttpHeader[] headers = [HttpHeader("Content-Type", "text/plain; charset=utf-8")];

this(Socket sock){ super(sock); }

override void handle(HttpRequest req) {
respondWith("Hello, world!", 200, headers);
}
Expand Down
2 changes: 1 addition & 1 deletion bench/static_http/hello_threaded.d
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class HelloWorldProcessor : HttpProcessor {
HttpHeader[] headers = [HttpHeader("Content-Type", "text/plain; charset=utf-8")];

this(Socket sock){ super(sock); }

override void handle(HttpRequest req) {
respondWith("Hello, world!", 200, headers);
}
Expand Down
30 changes: 15 additions & 15 deletions src/photon/ds/common.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ auto steal(T)(ref shared T arg)
}
}

ref T unshared(T)(ref shared T value)
ref T unshared(T)(ref shared T value)
if (!is(T : U*, U)) {
return *cast(T*)&value;
}

T unshared(T)(shared T value)
T unshared(T)(shared T value)
if (is(T == class)){
return *cast(T*)&value;
return *cast(T*)&value;
}

ref T* unshared(T)(ref shared(T)* value) {
Expand All @@ -29,15 +29,15 @@ ref T* unshared(T)(ref shared(T)* value) {

// intrusive list helper
T removeFromList(T)(T head, T item) {
if (head == item) return head.next;
else {
auto p = head;
while(p.next) {
if (p.next == item)
p.next = item.next;
else
p = p.next;
}
return head;
}
}
if (head == item) return head.next;
else {
auto p = head;
while(p.next) {
if (p.next == item)
p.next = item.next;
else
p = p.next;
}
return head;
}
}
6 changes: 3 additions & 3 deletions src/photon/ds/intrusive_queue.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ module photon.ds.intrusive_queue;
import photon.ds.common;
import core.internal.spinlock;

shared struct IntrusiveQueue(T, Event)
shared struct IntrusiveQueue(T, Event)
if (is(T : Object)) {
private:
SpinLock lock = SpinLock(SpinLock.Contention.brief);
T head;
T tail;
bool exhausted = true;
bool exhausted = true;
public:
Event event;

this(Event ev) {
event = ev;
}
Expand Down
4 changes: 2 additions & 2 deletions src/photon/ds/ring_queue.d
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct RingQueue(T, Event)
bool closed;
shared size_t refCount;
AlignedSpinLock lock;

this(size_t capacity, Event cts, Event rtr)
{
store = cast(T*)malloc(T.sizeof * capacity);
Expand Down Expand Up @@ -153,4 +153,4 @@ unittest {
assert(q.tryPop(result) && result == "world");
assert(!q.tryPop(result));
assert(q.empty);
}
}
26 changes: 13 additions & 13 deletions src/photon/freebsd/core.d
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ nothrow:
} while(r < 0 && errno == EINTR);
r.checked("event reset");
}
void trigger() {

void trigger() {
union U {
ulong cnt;
ubyte[8] bytes;
Expand All @@ -73,7 +73,7 @@ nothrow:
void close() {
.close(fd);
}

int fd;
}

Expand Down Expand Up @@ -102,7 +102,7 @@ nothrow:
timer_settime(timer, 0, &its, null);
}

void dispose() {
void dispose() {
timer_delete(timer).checked;
}
}
Expand Down Expand Up @@ -178,13 +178,13 @@ struct AwaitingFiber {
}
}

class FiberExt : Fiber {
class FiberExt : Fiber {
FiberExt next;
uint numScheduler;
int wakeFd; // recieves fd that woken us up

enum PAGESIZE = 4096;

this(void function() fn, uint numSched) nothrow {
super(fn);
numScheduler = numSched;
Expand All @@ -201,7 +201,7 @@ class FiberExt : Fiber {
}
}

FiberExt currentFiber;
FiberExt currentFiber;
shared RawEvent termination; // termination event, triggered once last fiber exits
shared pthread_t eventLoop; // event loop, runs outside of D runtime
shared int alive; // count of non-terminated Fibers scheduled
Expand Down Expand Up @@ -282,7 +282,7 @@ public void go(void delegate() func) {
f.schedule();
}

/// Convenience overload for goOnSameThread that accepts functions
/// Convenience overload for goOnSameThread that accepts functions.
public void goOnSameThread(void function() func) {
goOnSameThread({ func(); });
}
Expand Down Expand Up @@ -325,7 +325,7 @@ enum DescriptorState: uint {

// list of awaiting fibers
shared struct Descriptor {
ReaderState _readerState;
ReaderState _readerState;
AwaitingFiber* _readerWaits;
WriterState _writerState;
AwaitingFiber* _writerWaits;
Expand Down Expand Up @@ -412,7 +412,7 @@ extern(C) void graceful_shutdown_on_signal(int, siginfo_t*, void*)
_exit(9);
}

version(photon_tracing)
version(photon_tracing)
void printStats()
{
// TODO: report on various events in eventloop/scheduler
Expand All @@ -428,7 +428,7 @@ public void startloop()
uint threads = threadsPerCPU;
kq = kqueue();
enforce(kq != -1);

eventLoop = pthread_create(cast(pthread_t*)&eventLoop, null, &processEventsEntry, null);
initWorkQueues(threads);
}
Expand Down Expand Up @@ -626,7 +626,7 @@ extern(C) ssize_t write(int fd, const void *buf, size_t count)
extern(C) ssize_t accept(int sockfd, sockaddr *addr, socklen_t *addrlen)
{
return universalSyscall!(SYS_ACCEPT, "accept", SyscallKind.accept, Fcntl.explicit, EWOULDBLOCK)
(sockfd, cast(size_t) addr, cast(size_t) addrlen);
(sockfd, cast(size_t) addr, cast(size_t) addrlen);
}

extern(C) ssize_t accept4(int sockfd, sockaddr *addr, socklen_t *addrlen, int flags)
Expand Down Expand Up @@ -654,7 +654,7 @@ extern(C) size_t recv(int sockfd, void *buf, size_t len, int flags) nothrow {
src_addr.sin_port = 0;
src_addr.sin_addr.s_addr = htonl(INADDR_ANY);
ssize_t addrlen = sockaddr_in.sizeof;
return recvfrom(sockfd, buf, len, flags, cast(sockaddr*)&src_addr, &addrlen);
return recvfrom(sockfd, buf, len, flags, cast(sockaddr*)&src_addr, &addrlen);
}

extern(C) private ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
Expand Down
Loading
Loading