MultiThreaded Demo:

- fixing various race conditions throughout (usage of static vars, etc)
 - addition of a few lightweight mutexes (which are compiled out by default)
 - slight code rearrangement in discreteDynamicsWorld to facilitate multithreading
 - PoolAllocator::allocate() can now be called when pool is full without
     crashing (null pointer returned)
 - PoolAllocator allocate and freeMemory, are OPTIONALLY threadsafe
     (default is un-threadsafe)
 - CollisionDispatcher no longer checks if the pool allocator is full
     before calling allocate(), instead it just calls allocate() and
     checks if the return is null -- this avoids a race condition
 - SequentialImpulseConstraintSolver OPTIONALLY uses different logic in
     getOrInitSolverBody() to avoid a race condition with kinematic bodies
 - addition of 2 classes which together allow simulation islands to be run
   in parallel:
    - btSimulationIslandManagerMt
    - btDiscreteDynamicsWorldMt
 - MultiThreadedDemo example in the example browser demonstrating use of
   OpenMP, Microsoft PPL, and Intel TBB
 - use multithreading for other demos
 - benchmark demo: add parallel raycasting
This commit is contained in:
Lunkhound
2016-09-27 00:01:45 -07:00
parent f01389ded2
commit 1c3686ca51
48 changed files with 3168 additions and 197 deletions

View File

@@ -716,8 +716,64 @@ btSolverConstraint& btSequentialImpulseConstraintSolver::addTorsionalFrictionCon
int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body,btScalar timeStep)
{
#if BT_THREADSAFE
int solverBodyId = -1;
if ( !body.isStaticOrKinematicObject() )
{
// dynamic body
// Dynamic bodies can only be in one island, so it's safe to write to the companionId
solverBodyId = body.getCompanionId();
if ( solverBodyId < 0 )
{
if ( btRigidBody* rb = btRigidBody::upcast( &body ) )
{
solverBodyId = m_tmpSolverBodyPool.size();
btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
initSolverBody( &solverBody, &body, timeStep );
body.setCompanionId( solverBodyId );
}
}
}
else if ( body.isStaticObject() )
{
// all fixed bodies (inf mass) get mapped to a single solver id
if ( m_fixedBodyId < 0 )
{
m_fixedBodyId = m_tmpSolverBodyPool.size();
btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
initSolverBody( &fixedBody, 0, timeStep );
}
solverBodyId = m_fixedBodyId;
}
else
{
// kinematic
// Kinematic bodies can be in multiple islands at once, so it is a
// race condition to write to them, so we use an alternate method
// to record the solverBodyId
int uniqueId = body.getUniqueId();
const int INVALID_SOLVER_BODY_ID = -1;
if (uniqueId >= m_kinematicBodyUniqueIdToSolverBodyTable.size())
{
m_kinematicBodyUniqueIdToSolverBodyTable.resize(uniqueId + 1, INVALID_SOLVER_BODY_ID);
}
solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[ uniqueId ];
// if no table entry yet,
if ( solverBodyId == INVALID_SOLVER_BODY_ID )
{
// create a table entry for this body
btRigidBody* rb = btRigidBody::upcast( &body );
solverBodyId = m_tmpSolverBodyPool.size();
btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
initSolverBody( &solverBody, &body, timeStep );
m_kinematicBodyUniqueIdToSolverBodyTable[ uniqueId ] = solverBodyId;
}
}
btAssert( solverBodyId < m_tmpSolverBodyPool.size() );
return solverBodyId;
#else // BT_THREADSAFE
int solverBodyIdA = -1;
int solverBodyIdA = -1;
if (body.getCompanionId() >= 0)
{
@@ -749,6 +805,7 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject&
}
return solverBodyIdA;
#endif // BT_THREADSAFE
}
#include <stdio.h>
@@ -1263,7 +1320,9 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
{
bodies[i]->setCompanionId(-1);
}
#if BT_THREADSAFE
m_kinematicBodyUniqueIdToSolverBodyTable.resize( 0 );
#endif // BT_THREADSAFE
m_tmpSolverBodyPool.reserve(numBodies+1);
m_tmpSolverBodyPool.resize(0);