diff options
Diffstat (limited to 'src/uctx-setjmp.h')
-rw-r--r-- | src/uctx-setjmp.h | 109 |
1 files changed, 0 insertions, 109 deletions
diff --git a/src/uctx-setjmp.h b/src/uctx-setjmp.h deleted file mode 100644 index 33e187e..0000000 --- a/src/uctx-setjmp.h +++ /dev/null @@ -1,109 +0,0 @@ -/* uctx-setjmp.h - setjmp based user-space context switching - * - * Copyright (C) 2009 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/fiber.h> - -#include <stdio.h> -#include <stdlib.h> -#include <setjmp.h> -#ifdef VALGRIND -#include <valgrind/valgrind.h> -#endif - -#define STACK_GUARD 0xbad57ac4 - -struct tf_uctx { - int *stack_guard; - void *alloc; - jmp_buf jmpbuf; -#ifdef VALGRIND - unsigned int stack_id; -#endif - struct tf_fiber fiber; -}; - -#define set_stack(ptr) ({ __asm__("movl %0, %%esp" : : "r"(ptr)); }) -#define get_stack() ({ void *ptr; __asm__("movl %%esp, %0" : "=r"(ptr)); ptr; }) - -attribute_never_inline -static void *tf_uctx_start(tf_fiber_proc fiber_main, size_t private_size) -{ - struct tf_uctx *uctx; - - uctx = alloca(private_size); - if (setjmp(uctx->jmpbuf) != 0) { - fiber_main(uctx->fiber.data); - tf_exit(); - } - return uctx; -} - -static inline -struct tf_fiber *tf_uctx_create(tf_fiber_proc fiber_main, int private_size) -{ - size_t size = TF_STACK_SIZE; - struct tf_uctx *uctx; - void *stack, *old_stack, *stack_head, *stack_tail; -#ifdef VALGRIND - int stack_id; -#endif - - stack = malloc(size); - if (stack == NULL) - return NULL; -#ifdef VALGRIND - stack_id = VALGRIND_STACK_REGISTER(stack, size); -#endif - - /* Assumes stack grows up */ - stack_head = stack + size - 8; - stack_tail = stack; - - old_stack = get_stack(); - set_stack(stack_head); - uctx = tf_uctx_start(fiber_main, private_size + sizeof(struct tf_uctx)); - set_stack(old_stack); - -#ifdef VALGRIND - uctx->stack_id = stack_id; -#endif - uctx->alloc = stack; - uctx->stack_guard = stack_tail; - *uctx->stack_guard = STACK_GUARD; - - return &uctx->fiber; -} - -static inline -void tf_uctx_destroy(struct tf_fiber *fiber) -{ - struct tf_uctx *uctx = container_of(fiber, struct tf_uctx, fiber); -#ifdef VALGRIND - VALGRIND_STACK_DEREGISTER(uctx->stack_id); -#endif - free(uctx->alloc); -} - -static inline -int tf_uctx_transfer(struct tf_fiber *from, struct tf_fiber *to, int value) -{ - struct tf_uctx *ufrom = container_of(from, struct tf_uctx, fiber); - struct tf_uctx *uto = container_of(to, struct tf_uctx, fiber); - int r; - - TF_BUG_ON(unlikely(*ufrom->stack_guard != STACK_GUARD)); - - r = setjmp(ufrom->jmpbuf); - if (r == 0) - longjmp(uto->jmpbuf, value); - return r; -} |