/* fiber.h - libtf fiber manager header * * Copyright (C) 2009-2010 Timo Teräs * 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_FIBER_H #define TF_FIBER_H #include #include #include /* Fiber wakeup reasons */ #define TF_WAKEUP_NONE 0 #define TF_WAKEUP_IMMEDIATE -EAGAIN #define TF_WAKEUP_KILL -EINTR #define TF_WAKEUP_TIMEOUT -ETIME #define TF_WAKEUP_THIS_TIMEOUT -ETIMEDOUT #define TF_WAKEUP_FD -EIO /* Fiber management */ struct tf_scheduler; typedef void (*tf_fiber_proc)(void *fiber); void *__tf_fiber_create(tf_fiber_proc fiber_main, int private_size); void *tf_fiber_create(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); 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; }; #define tf_timed(func, timeout) \ ({ \ struct tf_timeout __timeout; \ tf_timeout_push(&__timeout, timeout); \ tf_timeout_pop(&__timeout, (func)); \ }) void tf_timeout_push(struct tf_timeout *timeout, tf_mtime_diff_t milliseconds); int __tf_timeout_pop(struct tf_timeout *timeout, int err); static inline int tf_timeout_pop(struct tf_timeout *timeout, int err) { if (unlikely(timeout->timeout_change)) return __tf_timeout_pop(timeout, err); return err; } static inline int tf_msleep(tf_mtime_diff_t milliseconds) { int r; r = tf_timed(__tf_fiber_schedule(), milliseconds); if (r == TF_WAKEUP_THIS_TIMEOUT) r = 0; return r; } #endif