Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenlib/intern/threads.cc
| Show All 31 Lines | |||||
| #endif | #endif | ||||
| #ifdef WITH_TBB | #ifdef WITH_TBB | ||||
| # include <tbb/spin_mutex.h> | # include <tbb/spin_mutex.h> | ||||
| #endif | #endif | ||||
| #include "atomic_ops.h" | #include "atomic_ops.h" | ||||
| #if defined(__APPLE__) && defined(_OPENMP) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) && \ | |||||
| !defined(__clang__) | |||||
| # define USE_APPLE_OMP_FIX | |||||
| #endif | |||||
| #ifdef USE_APPLE_OMP_FIX | |||||
| /* ************** 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 | * Basic Thread Control API | ||||
| * ======================== | * ======================== | ||||
| * | * | ||||
| * Many thread cases have an X amount of jobs, and only an Y amount of | * Many thread cases have an X amount of jobs, and only an Y amount of | ||||
| * threads are useful (typically amount of CPU's) | * threads are useful (typically amount of CPU's) | ||||
| * | * | ||||
| * This code can be used to start a maximum amount of 'thread slots', which | * This code can be used to start a maximum amount of 'thread slots', which | ||||
| ▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | if (threadbase != nullptr && tot > 0) { | ||||
| for (a = 0; a < tot; a++) { | for (a = 0; a < tot; a++) { | ||||
| ThreadSlot *tslot = static_cast<ThreadSlot *>(MEM_callocN(sizeof(ThreadSlot), "threadslot")); | ThreadSlot *tslot = static_cast<ThreadSlot *>(MEM_callocN(sizeof(ThreadSlot), "threadslot")); | ||||
| BLI_addtail(threadbase, tslot); | BLI_addtail(threadbase, tslot); | ||||
| tslot->do_thread = do_thread; | tslot->do_thread = do_thread; | ||||
| tslot->avail = 1; | tslot->avail = 1; | ||||
| } | } | ||||
| } | } | ||||
| uint level = atomic_fetch_and_add_u(&thread_levels, 1); | atomic_fetch_and_add_u(&thread_levels, 1); | ||||
| if (level == 0) { | |||||
| #ifdef USE_APPLE_OMP_FIX | |||||
| /* 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 | |||||
| } | |||||
| } | } | ||||
| int BLI_available_threads(ListBase *threadbase) | int BLI_available_threads(ListBase *threadbase) | ||||
| { | { | ||||
| int counter = 0; | int counter = 0; | ||||
| LISTBASE_FOREACH (ThreadSlot *, tslot, threadbase) { | LISTBASE_FOREACH (ThreadSlot *, tslot, threadbase) { | ||||
| if (tslot->avail) { | if (tslot->avail) { | ||||
| Show All 16 Lines | int BLI_threadpool_available_thread_index(ListBase *threadbase) | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| static void *tslot_thread_start(void *tslot_p) | static void *tslot_thread_start(void *tslot_p) | ||||
| { | { | ||||
| ThreadSlot *tslot = (ThreadSlot *)tslot_p; | ThreadSlot *tslot = (ThreadSlot *)tslot_p; | ||||
| #ifdef USE_APPLE_OMP_FIX | |||||
| /* 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); | return tslot->do_thread(tslot->callerdata); | ||||
| } | } | ||||
| int BLI_thread_is_main() | int BLI_thread_is_main() | ||||
| { | { | ||||
| return pthread_equal(pthread_self(), mainid); | return pthread_equal(pthread_self(), mainid); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 577 Lines • Show Last 20 Lines | |||||