summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingold2006-03-10 01:53:55 +0000
committergingold2006-03-10 01:53:55 +0000
commit04f194de79f5b4b44ac09c42bd926c7e7732bc54 (patch)
treeba6394b662801ad0031d5d3152708c8c08a0139a
parenta519edeff15246963006756abeef8ee304d371ff (diff)
downloadghdl-04f194de79f5b4b44ac09c42bd926c7e7732bc54.tar.gz
ghdl-04f194de79f5b4b44ac09c42bd926c7e7732bc54.tar.bz2
ghdl-04f194de79f5b4b44ac09c42bd926c7e7732bc54.zip
setjmp/longjmp moved from cbinding to config
-rw-r--r--translate/grt/config/linux.c25
-rw-r--r--translate/grt/config/pthread.c47
-rw-r--r--translate/grt/config/win32.c48
-rw-r--r--translate/grt/grt-cbinding.c24
4 files changed, 116 insertions, 28 deletions
diff --git a/translate/grt/config/linux.c b/translate/grt/config/linux.c
index 2fe92c0..6b73cb4 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 f0cee39..d42a753 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 583b885..18e5a2d 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 1f37d29..8885e12 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)