Repository: lucy-clownfish Updated Branches: refs/heads/master dafc3801b -> 13a9ccce3
Factor out thread-local storage code Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/76980a51 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/76980a51 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/76980a51 Branch: refs/heads/master Commit: 76980a516626770f60083dbd8cdec55317b85b35 Parents: dafc380 Author: Nick Wellnhofer <[email protected]> Authored: Sun May 10 21:11:50 2015 +0200 Committer: Nick Wellnhofer <[email protected]> Committed: Sat May 30 13:34:19 2015 +0200 ---------------------------------------------------------------------- runtime/c/src/Clownfish/Err.c | 149 +++++-------------------------------- runtime/c/src/tls.c | 140 ++++++++++++++++++++++++++++++++++ runtime/c/src/tls.h | 53 +++++++++++++ 3 files changed, 212 insertions(+), 130 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/76980a51/runtime/c/src/Clownfish/Err.c ---------------------------------------------------------------------- diff --git a/runtime/c/src/Clownfish/Err.c b/runtime/c/src/Clownfish/Err.c index 1956293..07a5233 100644 --- a/runtime/c/src/Clownfish/Err.c +++ b/runtime/c/src/Clownfish/Err.c @@ -23,150 +23,39 @@ #include <stdio.h> #include <stdlib.h> +#include "tls.h" #include "Clownfish/Err.h" #include "Clownfish/String.h" #include "Clownfish/Util/Memory.h" #include "Clownfish/Class.h" -typedef struct { - Err *current_error; - Err *thrown_error; - jmp_buf *current_env; -} cfish_ErrGlobals; - -/**************************** No thread support ****************************/ -#ifdef CFISH_NOTHREADS - -static cfish_ErrGlobals err_globals; - -void -Err_init_class() { -} - -static cfish_ErrGlobals* -S_get_globals() { - return &err_globals; -} - -/********************************** Windows ********************************/ -#elif defined(CHY_HAS_WINDOWS_H) - -#include <windows.h> - -static DWORD err_globals_tls_index; - -void -Err_init_class() { - err_globals_tls_index = TlsAlloc(); - if (err_globals_tls_index == TLS_OUT_OF_INDEXES) { - fprintf(stderr, "TlsAlloc failed (TLS_OUT_OF_INDEXES)\n"); - abort(); - } -} - -static cfish_ErrGlobals* -S_get_globals() { - cfish_ErrGlobals *globals - = (cfish_ErrGlobals*)TlsGetValue(err_globals_tls_index); - - if (!globals) { - globals = (cfish_ErrGlobals*)CALLOCATE(1, sizeof(cfish_ErrGlobals)); - if (!TlsSetValue(err_globals_tls_index, globals)) { - fprintf(stderr, "TlsSetValue failed: %d\n", GetLastError()); - abort(); - } - } - - return globals; -} - -BOOL WINAPI -DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved) { - if (reason == DLL_THREAD_DETACH) { - cfish_ErrGlobals *globals - = (cfish_ErrGlobals*)TlsGetValue(err_globals_tls_index); - - if (globals) { - DECREF(globals->current_error); - FREEMEM(globals); - } - } - - return TRUE; -} - -/******************************** pthreads *********************************/ -#elif defined(CHY_HAS_PTHREAD_H) - -#include <pthread.h> - -static pthread_key_t err_globals_key; - -static void -S_destroy_globals(void *globals); - void Err_init_class() { - int error = pthread_key_create(&err_globals_key, S_destroy_globals); - if (error) { - fprintf(stderr, "pthread_key_create failed: %d\n", error); - abort(); - } -} - -static cfish_ErrGlobals* -S_get_globals() { - cfish_ErrGlobals *globals - = (cfish_ErrGlobals*)pthread_getspecific(err_globals_key); - - if (!globals) { - globals = (cfish_ErrGlobals*)CALLOCATE(1, sizeof(cfish_ErrGlobals)); - int error = pthread_setspecific(err_globals_key, globals); - if (error) { - fprintf(stderr, "pthread_setspecific failed: %d\n", error); - abort(); - } - } - - return globals; + Tls_init(); } -static void -S_destroy_globals(void *arg) { - cfish_ErrGlobals *globals = (cfish_ErrGlobals*)arg; - DECREF(globals->current_error); - FREEMEM(globals); -} - -/****************** No support for thread-local storage ********************/ -#else - -#error "No support for thread-local storage." - -#endif - Err* Err_get_error() { - return S_get_globals()->current_error; + return Tls_get_err_context()->current_error; } void Err_set_error(Err *error) { - cfish_ErrGlobals *globals = S_get_globals(); + ErrContext *context = Tls_get_err_context(); - if (globals->current_error) { - DECREF(globals->current_error); + if (context->current_error) { + DECREF(context->current_error); } - globals->current_error = error; + context->current_error = error; } void Err_do_throw(Err *error) { - cfish_ErrGlobals *globals = S_get_globals(); + ErrContext *context = Tls_get_err_context(); - if (globals->current_env) { - globals->thrown_error = error; - longjmp(*globals->current_env, 1); + if (context->current_env) { + context->thrown_error = error; + longjmp(*context->current_env, 1); } else { String *message = Err_Get_Mess(error); @@ -193,21 +82,21 @@ Err_warn_mess(String *message) { } Err* -Err_trap(Err_Attempt_t routine, void *context) { - cfish_ErrGlobals *globals = S_get_globals(); +Err_trap(Err_Attempt_t routine, void *routine_context) { + ErrContext *err_context = Tls_get_err_context(); jmp_buf env; - jmp_buf *prev_env = globals->current_env; - globals->current_env = &env; + jmp_buf *prev_env = err_context->current_env; + err_context->current_env = &env; if (!setjmp(env)) { - routine(context); + routine(routine_context); } - globals->current_env = prev_env; + err_context->current_env = prev_env; - Err *error = globals->thrown_error; - globals->thrown_error = NULL; + Err *error = err_context->thrown_error; + err_context->thrown_error = NULL; return error; } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/76980a51/runtime/c/src/tls.c ---------------------------------------------------------------------- diff --git a/runtime/c/src/tls.c b/runtime/c/src/tls.c new file mode 100644 index 0000000..b550f13 --- /dev/null +++ b/runtime/c/src/tls.c @@ -0,0 +1,140 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CFISH_USE_SHORT_NAMES + +#include "charmony.h" + +#include <setjmp.h> +#include <stdio.h> +#include <stdlib.h> + +#include "tls.h" + +#include "Clownfish/Util/Memory.h" + +/**************************** No thread support ****************************/ +#ifdef CFISH_NOTHREADS + +static ErrContext err_context; + +void +Tls_init() { +} + +ErrContext* +Tls_get_err_context() { + return &err_context; +} + +/********************************** Windows ********************************/ +#elif defined(CHY_HAS_WINDOWS_H) + +#include <windows.h> + +static DWORD err_context_tls_index; + +void +Tls_init() { + err_context_tls_index = TlsAlloc(); + if (err_context_tls_index == TLS_OUT_OF_INDEXES) { + fprintf(stderr, "TlsAlloc failed (TLS_OUT_OF_INDEXES)\n"); + abort(); + } +} + +ErrContext* +Tls_get_err_context() { + ErrContext *context + = (ErrContext*)TlsGetValue(err_context_tls_index); + + if (!context) { + context = (ErrContext*)CALLOCATE(1, sizeof(ErrContext)); + if (!TlsSetValue(err_context_tls_index, context)) { + fprintf(stderr, "TlsSetValue failed: %d\n", GetLastError()); + abort(); + } + } + + return context; +} + +BOOL WINAPI +DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved) { + if (reason == DLL_THREAD_DETACH) { + ErrContext *context + = (ErrContext*)TlsGetValue(err_context_tls_index); + + if (context) { + DECREF(context->current_error); + FREEMEM(context); + } + } + + return TRUE; +} + +/******************************** pthreads *********************************/ +#elif defined(CHY_HAS_PTHREAD_H) + +#include <pthread.h> + +static pthread_key_t err_context_key; + +static void +S_destroy_context(void *context); + +void +Tls_init() { + int error = pthread_key_create(&err_context_key, S_destroy_context); + if (error) { + fprintf(stderr, "pthread_key_create failed: %d\n", error); + abort(); + } +} + +ErrContext* +Tls_get_err_context() { + ErrContext *context + = (ErrContext*)pthread_getspecific(err_context_key); + + if (!context) { + context = (ErrContext*)CALLOCATE(1, sizeof(ErrContext)); + int error = pthread_setspecific(err_context_key, context); + if (error) { + fprintf(stderr, "pthread_setspecific failed: %d\n", error); + abort(); + } + } + + return context; +} + +static void +S_destroy_context(void *arg) { + ErrContext *context = (ErrContext*)arg; + DECREF(context->current_error); + FREEMEM(context); +} + +/****************** No support for thread-local storage ********************/ +#else + +#error "No support for thread-local storage." + +#endif + + http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/76980a51/runtime/c/src/tls.h ---------------------------------------------------------------------- diff --git a/runtime/c/src/tls.h b/runtime/c/src/tls.h new file mode 100644 index 0000000..a430690 --- /dev/null +++ b/runtime/c/src/tls.h @@ -0,0 +1,53 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef H_CLOWNFISH_TLS +#define H_CLOWNFISH_TLS 1 + +#include "charmony.h" + +#include <setjmp.h> + +#include "Clownfish/Err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + Err *current_error; + Err *thrown_error; + jmp_buf *current_env; +} cfish_ErrContext; + +void +cfish_Tls_init(void); + +cfish_ErrContext* +cfish_Tls_get_err_context(); + +#ifdef CFISH_USE_SHORT_NAMES + #define ErrContext cfish_ErrContext + #define Tls_init cfish_Tls_init + #define Tls_get_err_context cfish_Tls_get_err_context +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* H_CLOWNFISH_TLS */ +
