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/ifc.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/ifc.c')
-rw-r--r-- | src/ifc.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/ifc.c b/src/ifc.c new file mode 100644 index 0000000..2dfafe8 --- /dev/null +++ b/src/ifc.c @@ -0,0 +1,57 @@ +/* ifc.c - inter fiber communications + * + * Copyright (C) 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 <libtf/atomic.h> +#include <libtf/fiber.h> + +void tf_ifc_queue(void *fiber, struct tf_ifc *ifc, tf_ifc_handler_t handler) +{ + struct tf_fiber *f = container_of(fiber, struct tf_fiber, data); + struct tf_ifc *old; + + TF_BUG_ON(ifc->next != NULL); + ifc->handler = handler; + do { + old = f->pending_ifc; + ifc->next = old; + } while (!tf_atomic_cmpxchg(&f->pending_ifc, old, ifc)); + + tf_fiber_wakeup(f); +} + +void tf_ifc_complete(void *fiber, struct tf_ifc *ifc, tf_ifc_handler_t handler) +{ + ifc->sender = tf_vmach_get_current_fiber(); + tf_ifc_queue(fiber, ifc, handler); + while (ifc->sender != NULL) + tf_fiber_schedule(); +} + +void tf_ifc_process_unordered(void) +{ + struct tf_fiber *f = tf_vmach_get_current_fiber(), *s; + struct tf_ifc *pending, *ifc; + + while (f->pending_ifc != NULL) { + pending = tf_atomic_xchg(&f->pending_ifc, NULL); + while (pending) { + ifc = pending; + pending = ifc->next; + ifc->handler(f->data, ifc); + s = ifc->sender; + ifc->next = NULL; + ifc->sender = NULL; + if (s != NULL) + tf_fiber_wakeup(s); + } + } +} |