From 6d1aa9770bb316834e8ceb579da2c7de9a4c1187 Mon Sep 17 00:00:00 2001 From: Vincent Loechner Date: Sun, 26 Feb 2012 13:15:06 +0100 Subject: [PATCH] First step toward a thread safe polylib: - different exception stacks in errors.c - protected a global allocation cache in vector.c Uncomment the //#define #THREAD_SAFE_POLYLIB in those two files to enable it. --- source/arith/errors.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++---- source/kernel/vector.c | 54 ++++++++++++++++++++++++++---------- 2 files changed, 108 insertions(+), 20 deletions(-) diff --git a/source/arith/errors.c b/source/arith/errors.c index 0c2e608..3c44715 100644 --- a/source/arith/errors.c +++ b/source/arith/errors.c @@ -100,6 +100,8 @@ #include #include +//#define THREAD_SAFE_POLYLIB + #include "arithmetique.h" /* global constants to designate exceptions. @@ -180,14 +182,50 @@ typedef struct } linear_exception_holder; +#define MAX_STACKED_CONTEXTS 64 + + +/***************************************************/ +/** Vincent's patch to enable POSIX multithreading */ +/** Feb. 2012 */ +/***************************************************/ +#ifdef THREAD_SAFE_POLYLIB +#include +#include + +pthread_once_t once_control = PTHREAD_ONCE_INIT; +pthread_key_t mt_key; +/* (int)exception_index is stored in the last+1 exception stack position */ +#define exception_index (exception_stack[MAX_STACKED_CONTEXTS-1].what) +linear_exception_holder *allocate_local_stack(void) +{ + linear_exception_holder *exception_stack; + exception_stack = malloc( sizeof(linear_exception_holder)*(MAX_STACKED_CONTEXTS+1) ); + assert( exception_stack!=NULL ); + exception_index = 0; + assert( pthread_setspecific( mt_key, exception_stack ) == 0 ); + return( exception_stack ); +} +void free_local_stack(void *es) +{ + free(es); + assert( pthread_setspecific(mt_key, NULL) == 0 ); +} +void init_multithreaded_stacks(void) +{ + pthread_key_create(&mt_key, free_local_stack); +} +#else // NO THREAD_SAFE_POLYLIB + /* exception stack. maximum extension. current index (next available bucket) */ -#define MAX_STACKED_CONTEXTS 64 static linear_exception_holder exception_stack[MAX_STACKED_CONTEXTS]; static int exception_index = 0; +#endif // THREAD_SAFE_POLYLIB + /* callbacks... */ static exception_callback_t push_callback = NULL; @@ -216,6 +254,12 @@ int linear_number_of_exception_thrown = 0; void dump_exception_stack_to_file(FILE * f) { int i; +#ifdef THREAD_SAFE_POLYLIB + linear_exception_holder *exception_stack; + if( (exception_stack = pthread_getspecific( mt_key )) == NULL ) + exception_stack = allocate_local_stack(); +#endif // THREAD_SAFE_POLYLIB + fprintf(f, "[dump_exception_stack_to_file] size=%d\n", exception_index); for (i=0; i #include +//#define THREAD_SAFE_POLYLIB + #ifdef MAC_OS #define abs __abs #endif @@ -765,37 +767,50 @@ static struct { } cache[MAX_CACHE_SIZE]; static int cache_size = 0; +#ifdef THREAD_SAFE_POLYLIB +#include + pthread_mutex_t cache_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + Value* value_alloc(int want, int *got) { int i; Value *p; +#ifdef THREAD_SAFE_POLYLIB + pthread_mutex_lock(&cache_mutex); +#endif if (cache_size) { - int best; + int best=0; for (i = 0; i < cache_size; ++i) { - if (cache[i].size >= want) { - Value *p = cache[i].p; - *got = cache[i].size; - if (--cache_size != i) - cache[i] = cache[cache_size]; - Vector_Set(p, 0, want); - return p; - } - if (i == 0) - best = 0; - else if (cache[i].size > cache[best].size) - best = i; + if (cache[i].size >= want) { + Value *p = cache[i].p; + *got = cache[i].size; + if (--cache_size != i) + cache[i] = cache[cache_size]; +#ifdef THREAD_SAFE_POLYLIB + pthread_mutex_unlock(&cache_mutex); +#endif + Vector_Set(p, 0, want); + return p; + } + if (cache[i].size > cache[best].size) + best = i; } p = (Value *)realloc(cache[best].p, want * sizeof(Value)); *got = cache[best].size; if (--cache_size != best) - cache[best] = cache[cache_size]; + cache[best] = cache[cache_size]; Vector_Set(p, 0, *got); - } else { + } + else { p = (Value *)malloc(want * sizeof(Value)); *got = 0; } +#ifdef THREAD_SAFE_POLYLIB + pthread_mutex_unlock(&cache_mutex); +#endif if (!p) return p; @@ -811,12 +826,21 @@ void value_free(Value *p, int size) { int i; +#ifdef THREAD_SAFE_POLYLIB + pthread_mutex_lock(&cache_mutex); +#endif if (cache_size < MAX_CACHE_SIZE) { cache[cache_size].p = p; cache[cache_size].size = size; ++cache_size; +#ifdef THREAD_SAFE_POLYLIB + pthread_mutex_unlock(&cache_mutex); +#endif return; } +#ifdef THREAD_SAFE_POLYLIB + pthread_mutex_unlock(&cache_mutex); +#endif for (i=0; i < size; i++) value_clear(p[i]); -- 2.11.4.GIT