19#if BT_USE_OPENMP && BT_THREADSAFE
25#if BT_USE_PPL && BT_THREADSAFE
34#if BT_USE_TBB && BT_THREADSAFE
37#define __TBB_NO_IMPLICIT_LINKAGE 1
39#include <tbb/task_scheduler_init.h>
40#include <tbb/parallel_for.h>
41#include <tbb/blocked_range.h>
53#if __cplusplus >= 201103L
57#define USE_CPP11_ATOMICS 1
59#elif defined(_MSC_VER)
62#define USE_MSVC_INTRINSICS 1
64#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
68#define USE_GCC_BUILTIN_ATOMICS 1
70#elif defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
73#define USE_GCC_BUILTIN_ATOMICS_OLD 1
82#define THREAD_LOCAL_STATIC thread_local static
86 std::atomic<int>*
aDest =
reinterpret_cast<std::atomic<int>*
>(&
mLock);
88 return std::atomic_compare_exchange_weak_explicit(
aDest, &
expected,
int(1), std::memory_order_acq_rel, std::memory_order_acquire);
102 std::atomic<int>*
aDest =
reinterpret_cast<std::atomic<int>*
>(&
mLock);
103 std::atomic_store_explicit(
aDest,
int(0), std::memory_order_release);
106#elif USE_MSVC_INTRINSICS
108#define WIN32_LEAN_AND_MEAN
113#define THREAD_LOCAL_STATIC __declspec(thread) static
117 volatile long*
aDest =
reinterpret_cast<long*
>(&
mLock);
132 volatile long*
aDest =
reinterpret_cast<long*
>(&
mLock);
136#elif USE_GCC_BUILTIN_ATOMICS
138#define THREAD_LOCAL_STATIC static __thread
163#elif USE_GCC_BUILTIN_ATOMICS_OLD
165#define THREAD_LOCAL_STATIC static __thread
189#error "no threading primitives defined -- unknown platform"
198 btAssert(!
"unimplemented btSpinMutex::lock() called");
203 btAssert(!
"unimplemented btSpinMutex::unlock() called");
208 btAssert(!
"unimplemented btSpinMutex::tryLock() called");
212#define THREAD_LOCAL_STATIC static
234 btAssert(!
"thread counter exceeded");
274#define BT_DETECT_BAD_THREAD_INDEX 0
276#if BT_DETECT_BAD_THREAD_INDEX
299#if BT_DETECT_BAD_THREAD_INDEX
315 btAssert(!
"there are 2 or more threads with the same thread-index!");
391 btAssert(!
"btSetTaskScheduler must be called from the main thread!");
416#if BT_DETECT_BAD_THREAD_INDEX
433 btAssert(!
"called btParallelFor in non-threadsafe build. enable BT_THREADSAFE");
443#if BT_DETECT_BAD_THREAD_INDEX
460 btAssert(!
"called btParallelFor in non-threadsafe build. enable BT_THREADSAFE");
489#if BT_USE_OPENMP && BT_THREADSAFE
518 m_savedThreadCounter = 0;
528#pragma omp parallel for schedule(static, 1)
541#pragma omp parallel for schedule(static, 1) reduction(+ \
554#if BT_USE_TBB && BT_THREADSAFE
580 return tbb::task_scheduler_init::default_num_threads();
596 m_savedThreadCounter = 0;
607 void operator()(
const tbb::blocked_range<int>&
range)
const
620 tbb::simple_partitioner());
631 void operator()(
const tbb::blocked_range<int>&
range)
649#if BT_USE_PPL && BT_THREADSAFE
656 concurrency::combinable<btScalar>
m_sum;
664 return concurrency::GetProcessorCount();
676 if (CurrentScheduler::Id() != -1)
678 CurrentScheduler::Detach();
684 policy.SetConcurrencyLimits(1, 1);
685 CurrentScheduler::Create(
policy);
686 CurrentScheduler::Detach();
689 CurrentScheduler::Create(
policy);
690 m_savedThreadCounter = 0;
703 void operator()(
int i)
const
716 concurrency::parallel_for(
iBegin,
725 concurrency::combinable<btScalar>*
mSum;
730 void operator()(
int i)
const
744 concurrency::parallel_for(
iBegin,
764#if BT_USE_OPENMP && BT_THREADSAFE
775#if BT_USE_TBB && BT_THREADSAFE
786#if BT_USE_PPL && BT_THREADSAFE
const T & btMax(const T &a, const T &b)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
static T sum(const btAlignedObjectArray< T > &items)
btITaskScheduler * btGetTBBTaskScheduler()
void btPopThreadsAreRunning()
btITaskScheduler * btGetPPLTaskScheduler()
void btResetThreadIndexCounter()
static btITaskScheduler * gBtTaskScheduler
btScalar btParallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody &body)
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
virtual btScalar sumLoop(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
virtual btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody &body)=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 btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody &body) BT_OVERRIDE
virtual int getNumThreads() const BT_OVERRIDE
btTaskSchedulerSequential()
virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody &body) BT_OVERRIDE