summaryrefslogtreecommitdiffstats
path: root/src/uctx.h
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 /src/uctx.h
parent43e69b26126b8708b70680c6b4806eb3844386ab (diff)
downloadlibtf-5ef38570315dc68d7ddf8d9475d9a8830528e8a4.tar.bz2
libtf-5ef38570315dc68d7ddf8d9475d9a8830528e8a4.tar.xz
libtf: separate scheduler fibre, change the core api
Diffstat (limited to 'src/uctx.h')
-rw-r--r--src/uctx.h82
1 files changed, 47 insertions, 35 deletions
diff --git a/src/uctx.h b/src/uctx.h
index 541fcf9..e27a53c 100644
--- a/src/uctx.h
+++ b/src/uctx.h
@@ -14,8 +14,12 @@
#include <stdio.h>
#include <stdlib.h>
+
#ifdef VALGRIND
#include <valgrind/valgrind.h>
+#else
+#define VALGRIND_STACK_REGISTER(stack_base, size) 0
+#define VALGRIND_STACK_DEREGISTER(stack_id)
#endif
#define STACK_GUARD 0xbad57ac4
@@ -24,10 +28,7 @@ struct tf_uctx {
int *stack_guard;
void *alloc;
void *current_sp;
-#ifdef VALGRIND
unsigned int stack_id;
-#endif
- struct tf_fiber fiber;
};
#if defined(__i386__)
@@ -86,10 +87,25 @@ static inline void stack_push_ptr(void **stackptr, void *ptr)
}
-static inline
-struct tf_fiber *tf_uctx_create(tf_fiber_proc fiber_main, int private_size)
+static inline void tf_uctx_create_self(struct tf_uctx *uctx)
+{
+ static int dummy_guard = STACK_GUARD;
+
+ *uctx = (struct tf_uctx) {
+ .stack_guard = &dummy_guard,
+ };
+}
+
+static inline void *
+tf_uctx_create_embedded(
+ size_t stack_size,
+ size_t private_size,
+ off_t uctx_offset,
+ void (*stack_frame_main)(void*), off_t main_argument_offset,
+ void (*stack_frame_return)(void))
{
size_t size = TF_STACK_SIZE;
+ void *user_data;
struct tf_uctx *uctx;
void *stack, *stack_base;
@@ -98,46 +114,42 @@ struct tf_fiber *tf_uctx_create(tf_fiber_proc fiber_main, int private_size)
if (stack_base == NULL)
return NULL;
+ /* Create initial stack frame (cdecl convention) */
stack = stack_pointer(stack_base, size);
- private_size += sizeof(struct tf_uctx);
-
- /* Construct inital frame for call the main function and if it
- * happens to return, it'll jump back to tf_exit() which kills
- * the fiber (cdecl calling convetion assumed) */
- uctx = stack_push(&stack, TF_ALIGN(private_size, 64));
- stack_push_ptr(&stack, uctx->fiber.data);
- stack_push_ptr(&stack, &tf_exit);
- stack_push_ptr(&stack, fiber_main);
- uctx->current_sp = stack;
-
-#ifdef VALGRIND
- uctx->stack_id = VALGRIND_STACK_REGISTER(stack_base, size);
-#endif
- uctx->alloc = stack_base;
- uctx->stack_guard = stack_guard(stack_base, size);
+ user_data = stack_push(&stack, TF_ALIGN(private_size, 64));
+ stack_push_ptr(&stack, NULL);
+ stack_push_ptr(&stack, NULL);
+ stack_push_ptr(&stack, NULL);
+ stack_push_ptr(&stack, NULL);
+ stack_push_ptr(&stack, user_data + main_argument_offset);
+ stack_push_ptr(&stack, stack_frame_return);
+ stack_push_ptr(&stack, stack_frame_main);
+
+ uctx = user_data + uctx_offset;
+ *uctx = (struct tf_uctx) {
+ .stack_guard = stack_guard(stack_base, size),
+ .alloc = stack_base,
+ .current_sp = stack,
+ .stack_id = VALGRIND_STACK_REGISTER(stack_base, size),
+ };
*uctx->stack_guard = STACK_GUARD;
- return &uctx->fiber;
+ return user_data;
}
static inline
-void tf_uctx_destroy(struct tf_fiber *fiber)
+void tf_uctx_destroy(struct tf_uctx *uctx)
{
- struct tf_uctx *uctx = container_of(fiber, struct tf_uctx, fiber);
-#ifdef VALGRIND
- VALGRIND_STACK_DEREGISTER(uctx->stack_id);
-#endif
- free(uctx->alloc);
+ if (uctx->alloc != NULL) {
+ VALGRIND_STACK_DEREGISTER(uctx->stack_id);
+ free(uctx->alloc);
+ }
}
static inline
-void tf_uctx_transfer(struct tf_fiber *from, struct tf_fiber *to)
+void tf_uctx_transfer(struct tf_uctx *from, struct tf_uctx *to)
{
-
- struct tf_uctx *ufrom = container_of(from, struct tf_uctx, fiber);
- struct tf_uctx *uto = container_of(to, struct tf_uctx, fiber);
-
/* Switch stack pointers */
- TF_BUG_ON(*ufrom->stack_guard != STACK_GUARD);
- switch_fiber(ufrom, uto);
+ TF_BUG_ON(*from->stack_guard != STACK_GUARD);
+ switch_fiber(from, to);
}