summaryrefslogtreecommitdiff
path: root/libco/sjlj.c
diff options
context:
space:
mode:
Diffstat (limited to 'libco/sjlj.c')
-rw-r--r--libco/sjlj.c115
1 files changed, 0 insertions, 115 deletions
diff --git a/libco/sjlj.c b/libco/sjlj.c
deleted file mode 100644
index f074714..0000000
--- a/libco/sjlj.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- libco.sjlj (2008-01-28)
- author: Nach
- license: public domain
-*/
-
-/*
- * Note this was designed for UNIX systems. Based on ideas expressed in a paper
- * by Ralf Engelschall.
- * For SJLJ on other systems, one would want to rewrite springboard() and
- * co_create() and hack the jmb_buf stack pointer.
- */
-
-#define LIBCO_C
-#include <libco.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <setjmp.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct
-{
- sigjmp_buf context;
- void (*coentry)(void);
- void *stack;
-} cothread_struct;
-
-static thread_local cothread_struct co_primary;
-static thread_local cothread_struct *creating, *co_running = 0;
-
-static void springboard(int ignored)
-{
- if(sigsetjmp(creating->context, 0))
- co_running->coentry();
-}
-
-cothread_t co_active(void)
-{
- if (!co_running)
- co_running = &co_primary;
- return (cothread_t)co_running;
-}
-
-cothread_t co_create(unsigned int size, void (*coentry)(void))
-{
- if(!co_running)
- co_running = &co_primary;
-
- cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct));
-
- if(thread)
- {
- struct sigaction handler;
- struct sigaction old_handler;
-
- stack_t stack;
- stack_t old_stack;
-
- thread->coentry = thread->stack = 0;
-
- stack.ss_flags = 0;
- stack.ss_size = size;
- thread->stack = stack.ss_sp = malloc(size);
-
- if(stack.ss_sp && !sigaltstack(&stack, &old_stack))
- {
- handler.sa_handler = springboard;
- handler.sa_flags = SA_ONSTACK;
- sigemptyset(&handler.sa_mask);
- creating = thread;
-
- if(!sigaction(SIGUSR1, &handler, &old_handler))
- {
- if(!raise(SIGUSR1))
- thread->coentry = coentry;
- sigaltstack(&old_stack, 0);
- sigaction(SIGUSR1, &old_handler, 0);
- }
- }
-
- if(thread->coentry != coentry)
- {
- co_delete(thread);
- thread = 0;
- }
- }
-
- return (cothread_t)thread;
-}
-
-void co_delete(cothread_t cothread)
-{
- if(cothread)
- {
- if(((cothread_struct*)cothread)->stack)
- free(((cothread_struct*)cothread)->stack);
- free(cothread);
- }
-}
-
-void co_switch(cothread_t cothread)
-{
- if(!sigsetjmp(co_running->context, 0))
- {
- co_running = (cothread_struct*)cothread;
- siglongjmp(co_running->context, 1);
- }
-}
-
-#ifdef __cplusplus
-}
-#endif