summaryrefslogtreecommitdiffstats
path: root/include/libtf
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2010-03-10 13:58:39 +0200
committerTimo Teras <timo.teras@iki.fi>2010-03-10 13:58:39 +0200
commit5ef38570315dc68d7ddf8d9475d9a8830528e8a4 (patch)
treef88fc542b5231614ac6c22a75baea90d82449d6c /include/libtf
parent43e69b26126b8708b70680c6b4806eb3844386ab (diff)
downloadlibtf-5ef38570315dc68d7ddf8d9475d9a8830528e8a4.tar.bz2
libtf-5ef38570315dc68d7ddf8d9475d9a8830528e8a4.tar.xz
libtf: separate scheduler fibre, change the core api
Diffstat (limited to 'include/libtf')
-rw-r--r--include/libtf/defines.h1
-rw-r--r--include/libtf/fiber.h82
-rw-r--r--include/libtf/heap.h10
-rw-r--r--include/libtf/io.h4
-rw-r--r--include/libtf/list.h33
-rw-r--r--include/libtf/scheduler.h64
-rw-r--r--include/libtf/tf.h1
7 files changed, 129 insertions, 66 deletions
diff --git a/include/libtf/defines.h b/include/libtf/defines.h
index ae72980..8e39c7e 100644
--- a/include/libtf/defines.h
+++ b/include/libtf/defines.h
@@ -62,6 +62,7 @@
__FILE__, __LINE__, __func__, #cond); \
abort(); \
}
+#define TF_BUILD_BUG_ON(cond) ((void) sizeof(struct { char TF_BUILD_BUG_ON[-!!(cond)]; }))
#define TF_ALIGN(size,align) ((((size_t)(size)) + (align)-1) & ~((align)-1))
diff --git a/include/libtf/fiber.h b/include/libtf/fiber.h
index ce3745b..a140607 100644
--- a/include/libtf/fiber.h
+++ b/include/libtf/fiber.h
@@ -1,6 +1,6 @@
-/* fiber.h - libtf fiber scheduler header
+/* fiber.h - libtf fiber manager header
*
- * Copyright (C) 2009 Timo Teräs <timo.teras@iki.fi>
+ * 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
@@ -15,8 +15,6 @@
#include <errno.h>
#include <libtf/defines.h>
-#include <libtf/atomic.h>
-#include <libtf/list.h>
#include <libtf/heap.h>
/* Fiber wakeup reasons */
@@ -27,64 +25,31 @@
#define TF_WAKEUP_THIS_TIMEOUT -ETIMEDOUT
#define TF_WAKEUP_FD -EIO
-struct tf_poll_data {
- int epoll_fd;
- int num_waiters;
-};
-
-/* Scheduler */
-struct tf_fiber;
+/* Fiber management */
+struct tf_scheduler;
+typedef void (*tf_fiber_proc)(void *fiber);
-struct tf_scheduler {
- struct tf_list_head run_q;
- struct tf_heap_head heap;
- struct tf_fiber * active_fiber;
- int num_fibers;
- tf_mtime_t scheduler_time;
- struct tf_poll_data poll_data;
-};
+void *__tf_fiber_create(tf_fiber_proc fiber_main, int private_size);
+void *tf_fiber_create(struct tf_scheduler *sched,
+ tf_fiber_proc fiber_main, int private_size);
+void *tf_fiber_get(void *data);
+void tf_fiber_put(void *data);
+void __tf_fiber_wakeup(void *data, int wakeup_type);
+void __tf_fiber_wakeup_heapnode(struct tf_heap_node *node);
+int __tf_fiber_schedule(void);
+int __tf_fiber_bind_scheduler(struct tf_scheduler *sched);
+int __tf_fiber_release_scheduler(struct tf_scheduler *sched);
-struct tf_main_ctx {
- int argc;
- char ** argv;
-};
+void tf_fiber_exit(void) attribute_noreturn;
+void tf_fiber_kill(void *fiber);
+int tf_fiber_yield(void);
+/* Scheduling and fiber management */
struct tf_timeout {
tf_mtime_t saved_timeout;
unsigned int timeout_change;
};
-static inline
-struct tf_scheduler *tf_get_scheduler(void)
-{
- extern struct tf_scheduler *__tf_scheduler;
- return __tf_scheduler;
-}
-
-static inline
-struct tf_fiber *tf_get_fiber(void)
-{
- return tf_get_scheduler()->active_fiber;
-}
-
-static inline
-tf_mtime_t tf_mtime(void)
-{
- return tf_get_scheduler()->scheduler_time;
-}
-
-/* Fiber creation */
-typedef void (*tf_fiber_proc)(void *fiber);
-int tf_main_args(tf_fiber_proc fiber_main, int argc, char **argv);
-static inline int tf_main(tf_fiber_proc fiber_main)
-{
- return tf_main_args(fiber_main, 0, NULL);
-}
-
-void *tf_fiber_create(tf_fiber_proc fiber_main, int private_size);
-void *tf_fiber_get(void *data);
-void tf_fiber_put(void *data);
-
#define tf_timed(func, timeout) \
({ \
struct tf_timeout __timeout; \
@@ -92,7 +57,6 @@ void tf_fiber_put(void *data);
tf_timeout_pop(&__timeout, (func)); \
})
-//* Scheduling and fiber management */
void tf_timeout_push(struct tf_timeout *timeout, tf_mtime_diff_t milliseconds);
int __tf_timeout_pop(struct tf_timeout *timeout, int err);
@@ -103,17 +67,11 @@ static inline int tf_timeout_pop(struct tf_timeout *timeout, int err)
return err;
}
-int tf_schedule(void);
-void tf_wakeup(struct tf_fiber *fiber, int wakeup_type);
-void tf_exit(void) attribute_noreturn;
-void tf_kill(void *fiber);
-int tf_yield(void);
-
static inline
int tf_msleep(tf_mtime_diff_t milliseconds)
{
int r;
- r = tf_timed(tf_schedule(), milliseconds);
+ r = tf_timed(__tf_fiber_schedule(), milliseconds);
if (r == TF_WAKEUP_THIS_TIMEOUT)
r = 0;
return r;
diff --git a/include/libtf/heap.h b/include/libtf/heap.h
index a68e01d..3a16159 100644
--- a/include/libtf/heap.h
+++ b/include/libtf/heap.h
@@ -74,4 +74,14 @@ int tf_heap_prealloc(struct tf_heap_head *head, uint32_t size)
return 0;
}
+static inline
+void tf_heap_destroy(struct tf_heap_head *head)
+{
+ if (head->item)
+ free(head->item);
+ head->item = NULL;
+ head->num_items = 0;
+ head->allocated = 0;
+}
+
#endif
diff --git a/include/libtf/io.h b/include/libtf/io.h
index 1f0b793..1f37d81 100644
--- a/include/libtf/io.h
+++ b/include/libtf/io.h
@@ -26,8 +26,6 @@
#define TF_FD_SET_CLOEXEC 4
#define TF_FD_ALREADY_NONBLOCKING 8
-struct tf_fiber;
-
struct tf_sockaddr {
union {
struct sockaddr addr;
@@ -42,7 +40,7 @@ struct tf_fd {
/* Single waiter -- would be relatively trivial to modify to allow
* multiple waiters, if someone actually needs it */
unsigned int events;
- struct tf_fiber *waiting_fiber;
+ void *waiting_fiber;
};
void tf_poll_init(void);
diff --git a/include/libtf/list.h b/include/libtf/list.h
index 22b76a8..f75a0be 100644
--- a/include/libtf/list.h
+++ b/include/libtf/list.h
@@ -142,7 +142,7 @@ static inline void tf_list_add_tail(struct tf_list_node *new, struct tf_list_hea
tf_list_add_before(new, &head->node);
}
-static inline void __tf_list_del(struct tf_list_node * prev, struct tf_list_node *next)
+static inline void __tf_list_del(struct tf_list_node *prev, struct tf_list_node *next)
{
next->prev = prev;
prev->next = next;
@@ -155,6 +155,14 @@ static inline void tf_list_del(struct tf_list_node *entry)
entry->prev = NULL;
}
+static inline struct tf_list_node *tf_list_pop(struct tf_list_head *head)
+{
+ struct tf_list_node *n;
+ n = head->node.next;
+ tf_list_del(n);
+ return n;
+}
+
static inline int tf_list_hashed(const struct tf_list_node *n)
{
return n->next != n && n->next != NULL;
@@ -165,6 +173,29 @@ static inline int tf_list_empty(const struct tf_list_head *h)
return !tf_list_hashed(&h->node);
}
+static inline void __tf_list_splice(const struct tf_list_head *list,
+ struct tf_list_node *prev,
+ struct tf_list_node *next)
+{
+ struct tf_list_node *first = list->node.next;
+ struct tf_list_node *last = list->node.prev;
+
+ first->prev = prev;
+ prev->next = first;
+
+ last->next = next;
+ next->prev = last;
+}
+
+static inline void tf_list_splice_tail(struct tf_list_head *src,
+ struct tf_list_head *dst)
+{
+ if (!tf_list_empty(src)) {
+ __tf_list_splice(src, dst->node.prev, &dst->node);
+ tf_list_init_head(src);
+ }
+}
+
#define tf_list_next(ptr, type, member) \
(tf_list_hashed(ptr) ? container_of((ptr)->next,type,member) : NULL)
diff --git a/include/libtf/scheduler.h b/include/libtf/scheduler.h
new file mode 100644
index 0000000..cc8db70
--- /dev/null
+++ b/include/libtf/scheduler.h
@@ -0,0 +1,64 @@
+/* scheduler.h - libtf fiber scheduler header
+ *
+ * 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.
+ */
+
+#ifndef TF_SCHEDULER_H
+#define TF_SCHEDULER_H
+
+#include <libtf/atomic.h>
+#include <libtf/list.h>
+#include <libtf/heap.h>
+#include <libtf/fiber.h>
+
+struct tf_scheduler {
+ struct tf_list_head scheduled_q;
+ struct tf_list_head running_q;
+ struct tf_heap_head heap;
+ void * active_fiber;
+ void * main_fiber;
+ int num_fibers;
+ tf_mtime_t scheduler_time;
+ unsigned long poll_data[2];
+};
+
+static inline
+struct tf_scheduler *tf_scheduler_get_current(void)
+{
+ extern struct tf_scheduler *__tf_scheduler;
+ TF_BUG_ON(__tf_scheduler == NULL);
+ return __tf_scheduler;
+}
+
+static inline
+tf_mtime_t tf_scheduler_get_mtime(void)
+{
+ return tf_scheduler_get_current()->scheduler_time;
+}
+
+struct tf_scheduler *tf_scheduler_create(void);
+int tf_scheduler_enable(struct tf_scheduler *);
+void tf_scheduler_disable(void);
+
+static inline struct tf_scheduler *
+tf_scheduler_get(struct tf_scheduler *s)
+{
+ tf_fiber_get(s);
+ return s;
+}
+
+static inline void
+tf_scheduler_put(struct tf_scheduler *s)
+{
+ tf_fiber_put(s);
+}
+
+#endif
+
diff --git a/include/libtf/tf.h b/include/libtf/tf.h
index 7a089ff..e613f18 100644
--- a/include/libtf/tf.h
+++ b/include/libtf/tf.h
@@ -14,6 +14,7 @@
#define TF_H
#include <libtf/fiber.h>
+#include <libtf/scheduler.h>
#include <libtf/io.h>
#endif