diff options
Diffstat (limited to 'src/scheduler.c')
-rw-r--r-- | src/scheduler.c | 134 |
1 files changed, 0 insertions, 134 deletions
diff --git a/src/scheduler.c b/src/scheduler.c deleted file mode 100644 index a103d0a..0000000 --- a/src/scheduler.c +++ /dev/null @@ -1,134 +0,0 @@ -/* scheduler.c - fiber scheduling - * - * Copyright (C) 2009-2010 Timo Teräs <timo.teras@iki.fi> - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 or later as - * published by the Free Software Foundation. - * - * See http://www.gnu.org/ for details. - */ - -#include <time.h> -#include <libtf/scheduler.h> -#include <libtf/io.h> - -/* FIXME: should be in thread local storage */ -extern struct tf_poll_hooks tf_epoll_hooks; -struct tf_scheduler *__tf_scheduler; - -static void update_time(struct tf_scheduler *sched) -{ - struct timespec ts; - - clock_gettime(CLOCK_MONOTONIC, &ts); - sched->scheduler_time = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; -} - -static void process_heap(struct tf_scheduler *sched) -{ - struct tf_heap_node *node; - tf_mtime_t now = sched->scheduler_time; - - while (!tf_heap_empty(&sched->heap) && - tf_mtime_diff(now, tf_heap_get_value(&sched->heap)) >= 0) { - node = tf_heap_get_node(&sched->heap); - tf_heap_delete(node, &sched->heap); - __tf_fiber_wakeup_heapnode(node); - } -} - -void tf_scheduler_fiber(void *data) -{ - struct tf_scheduler *sched = (struct tf_scheduler *) data; - - do { - tf_mtime_diff_t timeout; - - update_time(sched); - if (!tf_list_empty(&sched->scheduled_q) || - !tf_list_empty(&sched->running_q)) { - timeout = 0; - } else if (!tf_heap_empty(&sched->heap)) { - timeout = tf_mtime_diff( - tf_heap_get_value(&sched->heap), - tf_scheduler_get_mtime()); - if (timeout < 0) - timeout = 0; - } else { - timeout = -1; - } - - if (sched->poller->poll(timeout) == TF_WAKEUP_TIMEOUT && - timeout >= 0) { - sched->scheduler_time += timeout; - process_heap(sched); - } - - if (tf_fiber_yield() == TF_WAKEUP_KILL) { - do { - tf_fiber_put(sched->active_fiber); - sched->active_fiber = sched; - } while (__tf_fiber_schedule() == TF_WAKEUP_KILL); - } - } while (1); -} - -struct tf_scheduler *tf_scheduler_create(void) -{ - struct tf_scheduler *sched; - - sched = __tf_fiber_create(tf_scheduler_fiber, - sizeof(struct tf_scheduler)); - - *sched = (struct tf_scheduler) { - .scheduled_q = TF_LIST_HEAD_INITIALIZER(sched->scheduled_q), - .running_q = TF_LIST_HEAD_INITIALIZER(sched->running_q), - }; - - return sched; -} - -int tf_scheduler_enable(struct tf_scheduler *sched) -{ - struct tf_scheduler *s = sched; - - if (s == NULL) { - s = tf_scheduler_create(); - if (s == NULL) - return -ENOMEM; - } - if (s->main_fiber != NULL) - return -EBUSY; - - __tf_fiber_bind_scheduler(s); - __tf_scheduler = s; - s->poller = &tf_epoll_hooks; - s->poller->init(); - update_time(s); - - if (sched != NULL) - tf_scheduler_get(sched); - - return 0; -} - -void tf_scheduler_disable(void) -{ - struct tf_scheduler *sched = __tf_scheduler; - - if (sched == NULL || - sched->main_fiber != sched->active_fiber) - return; - - /* sleep until no others */ - while (sched->num_fibers > 1) - __tf_fiber_schedule(); - - sched->poller->close(); - __tf_scheduler = NULL; - __tf_fiber_release_scheduler(sched); - tf_heap_destroy(&sched->heap); - tf_fiber_put(sched); -} |