From 49e63d1fcc666d88d781f35074153e6943d62379 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Laferri=C3=A8re?= Date: Sun, 20 May 2018 19:17:12 -0400 Subject: [PATCH] nitc: use pthread_key_create and others when __thread is not available MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- src/compiler/abstract_compiler.nit | 73 ++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index cff93bd..b0cbd03 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -782,7 +782,7 @@ struct catch_stack_t { int currentSize; jmp_buf *envs; }; -extern __thread struct catch_stack_t catchStack; +extern struct catch_stack_t *getCatchStack(); """ end @@ -883,7 +883,44 @@ extern void nitni_global_ref_decr( struct nitni_ref *ref ); v.add_decl("int glob_argc;") v.add_decl("char **glob_argv;") v.add_decl("val *glob_sys;") - v.add_decl("__thread struct catch_stack_t catchStack = \{-1, 0, NULL\};") + + # Store catch stack in thread local storage + v.add_decl """ +#if defined(TARGET_OS_IPHONE) + // Use pthread_key_create and others for iOS + #include + + static pthread_key_t catch_stack_key; + static pthread_once_t catch_stack_key_created = PTHREAD_ONCE_INIT; + + static void create_catch_stack() + { + pthread_key_create(&catch_stack_key, NULL); + } + + struct catch_stack_t *getCatchStack() + { + pthread_once(&catch_stack_key_created, &create_catch_stack); + struct catch_stack_t *data = pthread_getspecific(catch_stack_key); + if (data == NULL) { + data = malloc(sizeof(struct catch_stack_t)); + data->cursor = -1; + data->currentSize = 0; + data->envs = NULL; + pthread_setspecific(catch_stack_key, data); + } + return data; + } +#else + // Use __thread when available + __thread struct catch_stack_t catchStack = {-1, 0, NULL}; + + struct catch_stack_t *getCatchStack() + { + return &catchStack; + } +#endif +""" if self.modelbuilder.toolcontext.opt_typing_test_metrics.value then for tag in count_type_test_tags do @@ -1876,8 +1913,11 @@ abstract class AbstractCompilerVisitor # This method should be called before the error messages and before a `add_raw_abort`. fun add_raw_throw do - self.add("if(catchStack.cursor >= 0)\{") - self.add("longjmp(catchStack.envs[catchStack.cursor], 1);") + self.add("\{") + self.add("struct catch_stack_t *catchStack = getCatchStack();") + self.add("if(catchStack->cursor >= 0)\{") + self.add(" longjmp(catchStack->envs[catchStack->cursor], 1);") + self.add("\}") self.add("\}") end @@ -3521,22 +3561,25 @@ redef class ADoExpr redef fun stmt(v) do if self.n_catch != null then - v.add("if(catchStack.currentSize == 0) \{") - v.add(" catchStack.cursor = -1;") - v.add(" catchStack.currentSize = 100;") - v.add(" catchStack.envs = malloc(sizeof(jmp_buf)*100);") - v.add("\} else if(catchStack.cursor == catchStack.currentSize - 1) \{") - v.add(" catchStack.currentSize *= 2;") - v.add(" catchStack.envs = realloc(catchStack.envs, sizeof(jmp_buf)*catchStack.currentSize);") + v.add("\{") + v.add("struct catch_stack_t *catchStack = getCatchStack();") + v.add("if(catchStack->currentSize == 0) \{") + v.add(" catchStack->cursor = -1;") + v.add(" catchStack->currentSize = 100;") + v.add(" catchStack->envs = malloc(sizeof(jmp_buf)*100);") + v.add("\} else if(catchStack->cursor == catchStack->currentSize - 1) \{") + v.add(" catchStack->currentSize *= 2;") + v.add(" catchStack->envs = realloc(catchStack->envs, sizeof(jmp_buf)*catchStack->currentSize);") v.add("\}") - v.add("catchStack.cursor += 1;") - v.add("if(!setjmp(catchStack.envs[catchStack.cursor]))\{") + v.add("catchStack->cursor += 1;") + v.add("if(!setjmp(catchStack->envs[catchStack->cursor]))\{") v.stmt(self.n_block) - v.add("catchStack.cursor -= 1;") + v.add("catchStack->cursor -= 1;") v.add("\}else \{") - v.add("catchStack.cursor -= 1;") + v.add("catchStack->cursor -= 1;") v.stmt(self.n_catch) v.add("\}") + v.add("\}") else v.stmt(self.n_block) end -- 1.7.9.5