21#if BT_USE_OPENMP && BT_THREADSAFE
28#if BT_USE_PPL && BT_THREADSAFE
38#if BT_USE_TBB && BT_THREADSAFE
41#define __TBB_NO_IMPLICIT_LINKAGE 1
43#include <tbb/task_scheduler_init.h>
44#include <tbb/parallel_for.h>
45#include <tbb/blocked_range.h>
58#if __cplusplus >= 201103L
62#define USE_CPP11_ATOMICS 1
64#elif defined( _MSC_VER )
67#define USE_MSVC_INTRINSICS 1
69#elif defined( __GNUC__ ) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
73#define USE_GCC_BUILTIN_ATOMICS 1
75#elif defined( __GNUC__ ) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
78#define USE_GCC_BUILTIN_ATOMICS_OLD 1
88#define THREAD_LOCAL_STATIC thread_local static
92 std::atomic<int>*
aDest =
reinterpret_cast<std::atomic<int>*
>(&
mLock);
94 return std::atomic_compare_exchange_weak_explicit(
aDest, &
expected,
int(1), std::memory_order_acq_rel, std::memory_order_acquire );
108 std::atomic<int>*
aDest =
reinterpret_cast<std::atomic<int>*
>(&
mLock);
109 std::atomic_store_explicit(
aDest,
int(0), std::memory_order_release );
113#elif USE_MSVC_INTRINSICS
115#define WIN32_LEAN_AND_MEAN
120#define THREAD_LOCAL_STATIC __declspec( thread ) static
125 volatile long*
aDest =
reinterpret_cast<long*
>(&
mLock);
140 volatile long*
aDest =
reinterpret_cast<long*
>( &
mLock );
144#elif USE_GCC_BUILTIN_ATOMICS
146#define THREAD_LOCAL_STATIC static __thread
172#elif USE_GCC_BUILTIN_ATOMICS_OLD
175#define THREAD_LOCAL_STATIC static __thread
199#error "no threading primitives defined -- unknown platform"
208 btAssert( !
"unimplemented btSpinMutex::lock() called" );
213 btAssert( !
"unimplemented btSpinMutex::unlock() called" );
218 btAssert( !
"unimplemented btSpinMutex::tryLock() called" );
222#define THREAD_LOCAL_STATIC static
245 btAssert( !
"thread counter exceeded" );
287#define BT_DETECT_BAD_THREAD_INDEX 0
289#if BT_DETECT_BAD_THREAD_INDEX
313#if BT_DETECT_BAD_THREAD_INDEX
329 btAssert( !
"there are 2 or more threads with the same thread-index!" );
406 btAssert( !
"btSetTaskScheduler must be called from the main thread!" );
433#if BT_DETECT_BAD_THREAD_INDEX
450 btAssert( !
"called btParallelFor in non-threadsafe build. enable BT_THREADSAFE" );
476#if BT_USE_OPENMP && BT_THREADSAFE
504 m_savedThreadCounter = 0;
514#pragma omp parallel for schedule( static, 1 )
526#if BT_USE_TBB && BT_THREADSAFE
552 return tbb::task_scheduler_init::default_num_threads();
568 m_savedThreadCounter = 0;
578 void operator()(
const tbb::blocked_range<int>&
range )
const
593 tbb::simple_partitioner()
601#if BT_USE_PPL && BT_THREADSAFE
615 return concurrency::GetProcessorCount();
627 if ( CurrentScheduler::Id() != -1 )
629 CurrentScheduler::Detach();
635 policy.SetConcurrencyLimits( 1, 1 );
636 CurrentScheduler::Create(
policy );
637 CurrentScheduler::Detach();
640 CurrentScheduler::Create(
policy );
641 m_savedThreadCounter = 0;
653 void operator()(
int i )
const
669 concurrency::parallel_for(
iBegin,
691#if BT_USE_OPENMP && BT_THREADSAFE
703#if BT_USE_TBB && BT_THREADSAFE
715#if BT_USE_PPL && BT_THREADSAFE
const T & btMax(const T &a, const T &b)
btITaskScheduler * btGetTBBTaskScheduler()
void btPopThreadsAreRunning()
btITaskScheduler * btGetPPLTaskScheduler()
void btResetThreadIndexCounter()
static btITaskScheduler * gBtTaskScheduler
static btSpinMutex gThreadsRunningCounterMutex
bool btThreadsAreRunning()
void btPushThreadsAreRunning()
static int gThreadsRunningCounter
btITaskScheduler * btGetOpenMPTaskScheduler()
unsigned int btGetCurrentThreadIndex()
static ThreadsafeCounter gThreadCounter
void btSetTaskScheduler(btITaskScheduler *ts)
btITaskScheduler * btGetTaskScheduler()
btITaskScheduler * btGetSequentialTaskScheduler()
#define THREAD_LOCAL_STATIC
void btParallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody &body)
void btResetThreadIndexCounter()
const unsigned int BT_MAX_THREAD_COUNT
virtual void forLoop(int iBegin, int iEnd) const =0
btITaskScheduler(const char *name)
virtual int getNumThreads() const =0
unsigned int m_savedThreadCounter
virtual int getMaxNumThreads() const =0
virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody &body)=0
virtual void deactivate()
virtual void setNumThreads(int numThreads)=0
btSpinMutex – lightweight spin-mutex implemented with atomic ops, never puts a thread to sleep becaus...
btTaskSchedulerSequential – non-threaded implementation of task scheduler (really just useful for tes...
virtual void setNumThreads(int numThreads) BT_OVERRIDE
virtual int getMaxNumThreads() const BT_OVERRIDE
virtual int getNumThreads() const BT_OVERRIDE
btTaskSchedulerSequential()
virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody &body) BT_OVERRIDE