summaryrefslogtreecommitdiffstats
path: root/src/fiber.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fiber.c')
-rw-r--r--src/fiber.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/fiber.c b/src/fiber.c
index 3f8bb15..6ddde1b 100644
--- a/src/fiber.c
+++ b/src/fiber.c
@@ -29,7 +29,7 @@ struct tf_fiber {
char data[TF_EMPTY_ARRAY];
};
-#include "uctx-setjmp.h"
+#include "uctx.h"
/* FIXME: should be in thread local storage */
struct tf_scheduler *__tf_scheduler;
@@ -91,12 +91,13 @@ static void run_fiber(struct tf_scheduler *sched, struct tf_fiber *f)
struct tf_fiber *schedf = container_of((void*) tf_get_scheduler(), struct tf_fiber, data);
sched->active_fiber = f;
- switch (tf_uctx_transfer(schedf, f, f->wakeup_type)) {
+ tf_uctx_transfer(schedf, f);
+ switch (f->wakeup_type) {
case TF_WAKEUP_KILL:
tf_fiber_put(f->data);
sched->num_fibers--;
break;
- case TF_WAKEUP_IMMEDIATE:
+ case TF_WAKEUP_NONE:
break;
default:
TF_BUG_ON("bad scheduler call from fiber");
@@ -222,15 +223,19 @@ int tf_schedule(void)
struct tf_fiber *f = sched->active_fiber;
if (unlikely(f->timeout_change)) {
- if (f->timeout_change & TF_TIMEOUT_CHANGE_NEW_VALUE)
+ if (f->timeout_change & TF_TIMEOUT_CHANGE_NEW_VALUE) {
+ if (tf_mtime_diff(f->timeout, tf_mtime()) <= 0) {
+ f->timeout_change = TF_TIMEOUT_CHANGE;
+ return TF_WAKEUP_TIMEOUT;
+ }
tf_heap_change(&f->heap_node, &sched->heap, f->timeout);
- else
+ } else
tf_heap_delete(&f->heap_node, &sched->heap);
f->timeout_change = 0;
}
f->wakeup_type = TF_WAKEUP_NONE;
-
- return tf_uctx_transfer(f, schedf, TF_WAKEUP_IMMEDIATE);
+ tf_uctx_transfer(f, schedf);
+ return f->wakeup_type;
}
void tf_wakeup(struct tf_fiber *fiber, int wakeup_type)
@@ -250,7 +255,8 @@ void tf_exit(void)
struct tf_fiber *schedf = container_of((void*) sched, struct tf_fiber, data);
tf_heap_delete(&f->heap_node, &sched->heap);
- tf_uctx_transfer(f, schedf, TF_WAKEUP_KILL);
+ f->wakeup_type = TF_WAKEUP_KILL;
+ tf_uctx_transfer(f, schedf);
TF_BUG_ON(1);
}