Skip to content
Snippets Groups Projects
Commit ff723a66 authored by Nicolas Pfeiffer's avatar Nicolas Pfeiffer
Browse files

fixes and clean up

parent 2805337a
No related branches found
No related tags found
No related merge requests found
......@@ -34,7 +34,7 @@ public:
__builtin_unreachable();
};
inline __attribute__((always_inline))
inline __attribute__((always_inline, returns_twice))
void setJmp() {
auto set_rip = [this] () __attribute__((noinline, hot, optimize(3))) {
ip = __builtin_return_address(0);
......
#pragma once
#include <mutex>
#include "Runtime.hpp"
#include "Fiber.hpp"
#include "Continuation.hpp"
......@@ -9,9 +11,10 @@
class Fibril : public Fiber {
public:
std::mutex m;
private:
int count; /* TODO make lock free thread-safe */
std::atomic<int> lock_var;
Continuation cont;
Context *stack;
......@@ -21,21 +24,22 @@ private:
inline void tryResume() {
int c;
lock();
m.lock();
c = --count;
unlock();
m.unlock();
if (c > 0) {
if (stack == Context::currentContext) {
Context::currentContext = nullptr;
}
/* randomSteal() */;
/* random steal */
return;
} else {
if (stack != Context::currentContext) {
Runtime::getRuntime()->getContextManager().putFreeContext(Context::currentContext);
Context::currentContext = stack;
}
/* resume, no return */
cont.execute(cont.sp);
}
}
......@@ -43,33 +47,22 @@ private:
public:
inline __attribute__((always_inline))
Fibril() : Fiber(Fiber::fiber_fun0_t(nullptr)), count(0), lock_var(1), cont() {
Fibril() : Fiber(Fiber::fiber_fun0_t(nullptr)), count(0), cont() {
stack = Context::currentContext; // TODO check if this is correct
};
~Fibril() {
assert(count == 0 && lock_var == 1); /* XXX DEBUG */
assert(count == 0); /* XXX DEBUG */
};
void run() override {
if (!count) count += 2;
if (!count) count = 2;
else count++;
unlock();
m.unlock();
cont.execute(Context::currentContext->getTos());
};
inline void lock() {
while (true) {
if (lock_var && lock_var.exchange(0))
return;
}
};
inline void unlock() {
lock_var = 1;
};
inline void resume() {
toResume = this;
Runtime::getRuntime()->getContextManager().resume();
......@@ -83,32 +76,32 @@ public:
inline __attribute__((always_inline))
void fork(Fiber::fiber_fun0_t fun) {
auto fork_func = [this, fun] () __attribute__((noinline, hot, optimize(3))) {
cont.ip = __builtin_return_address(0);
auto fork_func = [] (Fibril *fr, Fiber::fiber_fun0_t fun) __attribute__((noinline, hot, optimize(3))) {
fr->cont.ip = __builtin_return_address(0);
Runtime* runtime = Runtime::getRuntime();
runtime->pushBottom(*this);
runtime->pushBottom(*fr);
fun();
if (!runtime->popBottom()) { /* TODO laws Scheduler pushes to queues of other threads, handle that */
resume();
fr->resume();
}
};
membar(fork_func());
membar(fork_func(this, fun));
};
inline __attribute__((always_inline))
void fork(Fiber::fiber_fun_t fun, void *arg) {
auto fork_func = [this, fun, arg] () __attribute__((noinline, hot, optimize(3))) {
cont.ip = __builtin_return_address(0);
auto fork_func = [] (Fibril* fr, Fiber::fiber_fun_t fun, void* arg) __attribute__((noinline, hot, optimize(3))) {
fr->cont.ip = __builtin_return_address(0);
Runtime* runtime = Runtime::getRuntime();
runtime->pushBottom(*this);
runtime->pushBottom(*fr);
fun(arg);
if (!runtime->popBottom()) { /* TODO laws Scheduler pushes to queues of other threads, handle that */
resume();
fr->resume();
}
};
membar(fork_func());
membar(fork_func(this, fun, arg));
};
inline __attribute__((always_inline))
......@@ -116,12 +109,12 @@ public:
if (count == 0)
return;
auto join_func = [this] () __attribute__((noinline, hot, optimize(3))) {
cont.ip = __builtin_return_address(0);
resume();
auto join_func = [] (Fibril *fr) __attribute__((noinline, hot, optimize(3))) {
fr->cont.ip = __builtin_return_address(0);
fr->resume();
};
membar(join_func());
membar(join_func(this));
};
};
......
......@@ -40,7 +40,7 @@ namespace adt {
*itemPtr = deque.front();
if (Fibril* fr = dynamic_cast<Fibril*>(*itemPtr)) {
fr->lock();
fr->m.lock();
}
deque.pop_front();
......
......@@ -14,28 +14,20 @@ int64_t fibNums[36] = {
};
void fibtest(int n, int res) {
if (res != fibNums[n]) {
fprintf(stderr, "fib(%d) = %ld; was %d instead\n", n, fibNums[n], res);
exit(EXIT_FAILURE);
}
}
typedef struct {
int n;
int* result;
int64_t* result;
} fibParams;
fibril static void fib(void *voidParams) {
fibParams* params = static_cast<fibParams*>(voidParams);
int n = params->n;
int *result = params->result;
int64_t *result = params->result;
if (n < 2) {
*result = n;
} else {
int a, b;
int64_t a, b;
a = b = -1337;
Fibril *fr = new Fibril();
......@@ -58,22 +50,7 @@ fibril static void fib(void *voidParams) {
*result = a + b;
if (a != fibNums[n - 1]) {
fprintf(stderr, "fib(%d - 1) = %ld; was %d instead\n", n, fibNums[n - 1], a);
exit(EXIT_FAILURE);
}
if (b != fibNums[n - 2]) {
fprintf(stderr, "fib(%d - 2) = %ld; was %d instead\n", n, fibNums[n - 2], b);
exit(EXIT_FAILURE);
}
}
if (*result != fibNums[n]) {
fprintf(stderr, "fib(%d) = %ld; was %d instead\n", n, fibNums[n], *result);
exit(EXIT_FAILURE);
}
//fibtest(n, *result);
}
......@@ -83,17 +60,18 @@ int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) {
Fiber* fibFiber = Fiber::from([] (UNUSED_ARG void* arg) {
//const int fibNum = 13;
const int fibNum = 35;
//const int fibNum = 35;
const int fibNum = 42;
//const int expected = 233;
const int expected = 9227465;
//const int expected = 9227465;
const int64_t expected = 267914296;
int result;
int64_t result;
fibParams params = { fibNum, &result };
fib(&params);
if (result != expected) {
fprintf(stderr, "%d %d\n", expected, result);
exit(EXIT_FAILURE);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment