summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold2014-11-08 16:42:05 +0100
committerTristan Gingold2014-11-08 16:42:05 +0100
commit346a342c95e4cfa3502ac4991359ce2cd94f446a (patch)
tree9ad27d2c3fafb4c28d5449ab8ea5f8a897f56d3a /src
parent002b207d916c64b88a3bb691ee6c239139f49433 (diff)
downloadghdl-346a342c95e4cfa3502ac4991359ce2cd94f446a.tar.gz
ghdl-346a342c95e4cfa3502ac4991359ce2cd94f446a.tar.bz2
ghdl-346a342c95e4cfa3502ac4991359ce2cd94f446a.zip
Use _setjmp/_longjmp instead of setjmp/longjmp (much faster).
Diffstat (limited to 'src')
-rw-r--r--src/grt/config/linux.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/grt/config/linux.c b/src/grt/config/linux.c
index 74dce09..e468056 100644
--- a/src/grt/config/linux.c
+++ b/src/grt/config/linux.c
@@ -335,15 +335,48 @@ grt_stack_allocate (void)
return res;
}
-#include <setjmp.h>
+/* There is a simple setjmp/longjmp mechanism used to report failures.
+ We have the choice between 3 mechanisms:
+ * USE_BUITLIN_SJLJ: gcc builtin setjmp/longjmp, very fast but gcc specific.
+ * USE__SETJMP: _setjmp/_longjmp
+ * USE_SETJMP: setjmp/longjmp, slower because signals mask is saved/restored.
+*/
+
+#ifdef __GNUC__
+#define USE_BUILTIN_SJLJ
+#else
+#define USE__SETJMP
+#endif
+/* #define USE_SETJMP */
+
+#ifdef USE_BUILTIN_SJLJ
+typedef int *JMP_BUF[5];
+static int sjlj_val;
+# define SETJMP(BUF) (__builtin_setjmp (BUF), sjlj_val)
+# define LONGJMP(BUF, VAL) \
+ do { sjlj_val = (VAL); __builtin_longjmp (BUF, 1); } while (0)
+#else
+# include <setjmp.h>
+typedef jmp_buf JMP_BUF;
+# ifdef USE__SETJMP
+# define SETJMP _setjmp
+# define LONGJMP _longjmp
+# elsif defined (USE_SETJMP)
+# define SETJMP setjmp
+# define LONGJMP longjmp
+# else
+# error "SETJMP/LONGJMP not configued"
+# endif
+#endif
+
static int run_env_en;
-static jmp_buf run_env;
+static JMP_BUF run_env;
void
__ghdl_maybe_return_via_longjump (int val)
{
if (run_env_en)
- longjmp (run_env, val);
+ LONGJMP (run_env, val);
}
int
@@ -352,10 +385,9 @@ __ghdl_run_through_longjump (int (*func)(void))
int res;
run_env_en = 1;
- res = setjmp (run_env);
+ res = SETJMP (run_env);
if (res == 0)
res = (*func)();
run_env_en = 0;
return res;
}
-