diff options
author | Timo Teräs <timo.teras@iki.fi> | 2010-07-02 20:23:07 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2010-07-02 20:25:47 +0300 |
commit | 23b95bf1a15322c2f471b80c06cb65d9b2d2a282 (patch) | |
tree | 9bf12231db9591852e3b42ca24715d2cbaf6267b /src/scheduler.c | |
parent | 0183e33d9a4759764716e771b85e19f7a997b8bd (diff) | |
download | libtf-master.tar.bz2 libtf-master.tar.xz |
the idea is to make libtf completely multi-threaded. meaning each
fiber can be running concurrently in separate thread. quite a bit
of framework is added for this and some atomic helpers are already
introduced. however, io polling is busy polling now (will be soon
in own thread) and timeouts are still more or less broken. oh, and
the multithreading core is not there yet. basically we are currently
mostly broken ;)
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); -} |