diff options
author | gingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7> | 2006-03-10 01:53:55 +0000 |
---|---|---|
committer | gingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7> | 2006-03-10 01:53:55 +0000 |
commit | 04f194de79f5b4b44ac09c42bd926c7e7732bc54 (patch) | |
tree | ba6394b662801ad0031d5d3152708c8c08a0139a | |
parent | a519edeff15246963006756abeef8ee304d371ff (diff) | |
download | ghdl-04f194de79f5b4b44ac09c42bd926c7e7732bc54.tar.gz ghdl-04f194de79f5b4b44ac09c42bd926c7e7732bc54.tar.bz2 ghdl-04f194de79f5b4b44ac09c42bd926c7e7732bc54.zip |
setjmp/longjmp moved from cbinding to config
-rw-r--r-- | translate/grt/config/linux.c | 25 | ||||
-rw-r--r-- | translate/grt/config/pthread.c | 47 | ||||
-rw-r--r-- | translate/grt/config/win32.c | 48 | ||||
-rw-r--r-- | translate/grt/grt-cbinding.c | 24 |
4 files changed, 116 insertions, 28 deletions
diff --git a/translate/grt/config/linux.c b/translate/grt/config/linux.c index 2fe92c0fa..6b73cb476 100644 --- a/translate/grt/config/linux.c +++ b/translate/grt/config/linux.c @@ -285,3 +285,28 @@ grt_stack_allocate (void) res->cur_length = stack_size; return res; } + +#include <setjmp.h> +static int run_env_en; +static jmp_buf run_env; + +void +__ghdl_maybe_return_via_longjump (int val) +{ + if (run_env_en) + longjmp (run_env, val); +} + +int +__ghdl_run_through_longjump (int (*func)(void)) +{ + int res; + + run_env_en = 1; + res = setjmp (run_env); + if (res == 0) + res = (*func)(); + run_env_en = 0; + return res; +} + diff --git a/translate/grt/config/pthread.c b/translate/grt/config/pthread.c index f0cee39b1..d42a7532f 100644 --- a/translate/grt/config/pthread.c +++ b/translate/grt/config/pthread.c @@ -27,7 +27,7 @@ #include <pthread.h> #include <stdlib.h> #include <stdio.h> - +#include <setjmp.h> //#define INFO printf #define INFO (void) @@ -41,7 +41,8 @@ typedef struct void* Arg; // ARG passed to FUNC } Stack_Type_t, *Stack_Type; -Stack_Type_t main_stack_context; +static Stack_Type_t main_stack_context; +static Stack_Type_t *current; extern void grt_set_main_stack (Stack_Type_t *stack); //---------------------------------------------------------------------------- @@ -58,6 +59,8 @@ void grt_stack_init(void) // lock the mutex, as we are currently running pthread_mutex_lock(&(main_stack_context.mutex)); + current = &main_stack_context; + grt_set_main_stack (&main_stack_context); } @@ -115,6 +118,10 @@ Stack_Type grt_stack_create(void* Func, void* Arg) return newStack; } +static int need_longjmp; +static int run_env_en; +static jmp_buf run_env; + //---------------------------------------------------------------------------- void grt_stack_switch(Stack_Type To, Stack_Type From) // Resume stack TO and save the current context to the stack pointed by @@ -122,7 +129,9 @@ void grt_stack_switch(Stack_Type To, Stack_Type From) // => procedure Stack_Switch (To : Stack_Type; From : Stack_Type); { INFO("grt_stack_switch\n"); INFO(" from 0x%08x to 0x%08x\n", From, To); - + + current = To; + // unlock 'To' mutex. this will make the other thread either // - starts for first time in grt_stack_loop // - resumes at lock below @@ -132,6 +141,9 @@ void grt_stack_switch(Stack_Type To, Stack_Type From) // as we are running, our mutex is locked and we block here // when stacks are switched, with above unlock, we may proceed pthread_mutex_lock(&(From->mutex)); + + if (From == &main_stack_context && need_longjmp != 0) + longjmp (run_env, need_longjmp); } //---------------------------------------------------------------------------- @@ -141,6 +153,35 @@ void grt_stack_delete(Stack_Type Stack) { INFO("grt_stack_delete\n"); } +void +__ghdl_maybe_return_via_longjump (int val) +{ + if (!run_env_en) + return; + + if (current != &main_stack_context) + { + need_longjmp = val; + grt_stack_switch (&main_stack_context, current); + } + else + longjmp (run_env, val); +} + +int +__ghdl_run_through_longjump (int (*func)(void)) +{ + int res; + + run_env_en = 1; + res = setjmp (run_env); + if (res == 0) + res = (*func)(); + run_env_en = 0; + return res; +} + + //---------------------------------------------------------------------------- #ifndef WITH_GNAT_RUN_TIME diff --git a/translate/grt/config/win32.c b/translate/grt/config/win32.c index 583b885ba..18e5a2d4c 100644 --- a/translate/grt/config/win32.c +++ b/translate/grt/config/win32.c @@ -19,6 +19,8 @@ #include <windows.h> #include <stdio.h> +#include <setjmp.h> +#include <assert.h> struct stack_type { @@ -27,7 +29,8 @@ struct stack_type void *arg; // Function argument. }; -static struct stack_type main_stack_context; +static struct stack_type main_stack_context; +static struct stack_type *current; extern void grt_set_main_stack (struct stack_type *stack); void grt_stack_init(void) @@ -40,6 +43,7 @@ void grt_stack_init(void) abort (); } grt_set_main_stack (&main_stack_context); + current = &main_stack_context; } static VOID __stdcall @@ -71,10 +75,22 @@ grt_stack_create (void (*func)(void *), void *arg) return res; } +static int run_env_en; +static jmp_buf run_env; +static int need_longjmp; + void grt_stack_switch (struct stack_type *to, struct stack_type *from) { + assert (current == from); + current = to; SwitchToFiber (to->fiber); + if (from == &main_stack_context && need_longjmp) + { + /* We returned to do the longjump. */ + current = &main_stack_context; + longjmp (run_env, need_longjmp); + } } void @@ -84,6 +100,36 @@ grt_stack_delete (struct stack_type *stack) stack->fiber = NULL; } +void +__ghdl_maybe_return_via_longjump (int val) +{ + if (!run_env_en) + return; + + if (current != &main_stack_context) + { + /* We are allowed to jump only in the same stack. + First switch back to the main thread. */ + need_longjmp = val; + SwitchToFiber (main_stack_context.fiber); + } + else + longjmp (run_env, val); +} + +int +__ghdl_run_through_longjump (int (*func)(void)) +{ + int res; + + run_env_en = 1; + res = setjmp (run_env); + if (res == 0) + res = (*func)(); + run_env_en = 0; + return res; +} + #ifndef WITH_GNAT_RUN_TIME void __gnat_raise_storage_error(void) { diff --git a/translate/grt/grt-cbinding.c b/translate/grt/grt-cbinding.c index 1f37d2988..8885e1232 100644 --- a/translate/grt/grt-cbinding.c +++ b/translate/grt/grt-cbinding.c @@ -18,7 +18,6 @@ */ #include <stdio.h> #include <stdlib.h> -#include <setjmp.h> FILE * __ghdl_get_stdout (void) @@ -44,29 +43,6 @@ __ghdl_fprintf_g (FILE *stream, double val) fprintf (stream, "%g", val); } -static int run_env_en; -static jmp_buf run_env; - -void -__ghdl_maybe_return_via_longjump (int val) -{ - if (run_env_en) - longjmp (run_env, val); -} - -int -__ghdl_run_through_longjump (int (*func)(void)) -{ - int res; - - run_env_en = 1; - res = setjmp (run_env); - if (res == 0) - res = (*func)(); - run_env_en = 0; - return res; -} - #if 1 void __gnat_last_chance_handler (void) |