diff options
Diffstat (limited to 'source/blender/blenlib/intern/threads.c')
-rw-r--r-- | source/blender/blenlib/intern/threads.c | 85 |
1 files changed, 66 insertions, 19 deletions
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 371fae3dda2..726ed817f8b 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -28,15 +28,11 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include <math.h> -#include <stdlib.h> -#include <string.h> -#include <pthread.h> #include <errno.h> +#include <string.h> #include "MEM_guardedalloc.h" -#include "DNA_listBase.h" #include "BLI_blenlib.h" #include "BLI_gsqueue.h" @@ -56,6 +52,12 @@ #include <sys/time.h> #endif +#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) +/* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */ +extern pthread_key_t gomp_tls_key; +static void *thread_tls_data; +#endif + /* ********** basic thread control API ************ Many thread cases have an X amount of jobs, and only an Y amount of @@ -103,7 +105,11 @@ A sample loop can look like this (pseudo c); static pthread_mutex_t _malloc_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _preview_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _rcache_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_t mainid; static int thread_levels= 0; /* threads can be invoked inside threads */ /* just a max for security reasons */ @@ -127,6 +133,11 @@ static void BLI_unlock_malloc_thread(void) pthread_mutex_unlock(&_malloc_lock); } +void BLI_threadapi_init(void) +{ + mainid = pthread_self(); +} + /* tot = 0 only initializes malloc mutex in a safe way (see sequence.c) problem otherwise: scene render will kill of the mutex! */ @@ -134,7 +145,7 @@ static void BLI_unlock_malloc_thread(void) void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot) { int a; - + if(threadbase != NULL && tot > 0) { threadbase->first= threadbase->last= NULL; @@ -147,12 +158,20 @@ void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot) tslot->do_thread= do_thread; tslot->avail= 1; } - - if(thread_levels == 0) - MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread); - - thread_levels++; } + + if(thread_levels == 0) { + MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread); + +#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) + /* workaround for Apple gcc 4.2.1 omp vs background thread bug, + we copy gomp thread local storage pointer to setting it again + inside the thread that we start */ + thread_tls_data = pthread_getspecific(gomp_tls_key); +#endif + } + + thread_levels++; } /* amount of available threads */ @@ -181,6 +200,22 @@ int BLI_available_thread_index(ListBase *threadbase) return 0; } +static void *tslot_thread_start(void *tslot_p) +{ + ThreadSlot *tslot= (ThreadSlot*)tslot_p; + +#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) + /* workaround for Apple gcc 4.2.1 omp vs background thread bug, + set gomp thread local storage pointer which was copied beforehand */ + pthread_setspecific (gomp_tls_key, thread_tls_data); +#endif + + return tslot->do_thread(tslot->callerdata); +} + +int BLI_thread_is_main(void) { + return pthread_equal(pthread_self(), mainid); +} void BLI_insert_thread(ListBase *threadbase, void *callerdata) { @@ -190,7 +225,7 @@ void BLI_insert_thread(ListBase *threadbase, void *callerdata) if(tslot->avail) { tslot->avail= 0; tslot->callerdata= callerdata; - pthread_create(&tslot->pthread, NULL, tslot->do_thread, tslot->callerdata); + pthread_create(&tslot->pthread, NULL, tslot_thread_start, tslot); return; } } @@ -203,8 +238,8 @@ void BLI_remove_thread(ListBase *threadbase, void *callerdata) for(tslot= threadbase->first; tslot; tslot= tslot->next) { if(tslot->callerdata==callerdata) { - tslot->callerdata= NULL; pthread_join(tslot->pthread, NULL); + tslot->callerdata= NULL; tslot->avail= 1; } } @@ -217,8 +252,8 @@ void BLI_remove_thread_index(ListBase *threadbase, int index) for(tslot = threadbase->first; tslot; tslot = tslot->next, counter++) { if (counter == index && tslot->avail == 0) { - tslot->callerdata = NULL; pthread_join(tslot->pthread, NULL); + tslot->callerdata = NULL; tslot->avail = 1; break; } @@ -231,8 +266,8 @@ void BLI_remove_threads(ListBase *threadbase) for(tslot = threadbase->first; tslot; tslot = tslot->next) { if (tslot->avail == 0) { - tslot->callerdata = NULL; pthread_join(tslot->pthread, NULL); + tslot->callerdata = NULL; tslot->avail = 1; } } @@ -252,11 +287,11 @@ void BLI_end_threads(ListBase *threadbase) } } BLI_freelistN(threadbase); - - thread_levels--; - if(thread_levels==0) - MEM_set_lock_callback(NULL, NULL); } + + thread_levels--; + if(thread_levels==0) + MEM_set_lock_callback(NULL, NULL); } /* System Information */ @@ -301,8 +336,14 @@ void BLI_lock_thread(int type) pthread_mutex_lock(&_image_lock); else if (type==LOCK_PREVIEW) pthread_mutex_lock(&_preview_lock); + else if (type==LOCK_VIEWER) + pthread_mutex_lock(&_viewer_lock); else if (type==LOCK_CUSTOM1) pthread_mutex_lock(&_custom1_lock); + else if (type==LOCK_RCACHE) + pthread_mutex_lock(&_rcache_lock); + else if (type==LOCK_OPENGL) + pthread_mutex_lock(&_opengl_lock); } void BLI_unlock_thread(int type) @@ -311,8 +352,14 @@ void BLI_unlock_thread(int type) pthread_mutex_unlock(&_image_lock); else if (type==LOCK_PREVIEW) pthread_mutex_unlock(&_preview_lock); + else if (type==LOCK_VIEWER) + pthread_mutex_unlock(&_viewer_lock); else if(type==LOCK_CUSTOM1) pthread_mutex_unlock(&_custom1_lock); + else if(type==LOCK_RCACHE) + pthread_mutex_unlock(&_rcache_lock); + else if(type==LOCK_OPENGL) + pthread_mutex_unlock(&_opengl_lock); } /* Mutex Locks */ |