From 5ef38570315dc68d7ddf8d9475d9a8830528e8a4 Mon Sep 17 00:00:00 2001 From: Timo Teras Date: Wed, 10 Mar 2010 13:58:39 +0200 Subject: libtf: separate scheduler fibre, change the core api --- src/uctx.h | 82 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 35 deletions(-) (limited to 'src/uctx.h') 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 #include + #ifdef VALGRIND #include +#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); } -- cgit v1.2.3