Add posix thread backend to BulletMultiThreaded. Contributed by Enrico.

This commit is contained in:
john.mccutchan
2008-04-01 18:32:41 +00:00
parent 64df6edf39
commit ba27e0522b
13 changed files with 356 additions and 17 deletions

View File

@@ -45,6 +45,7 @@ ELSE (WIN32)
INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR})
# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY})
# TARGET_LINK_LIBRARIES(checker ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY})
LINK_LIBRARIES(AllBulletDemos pthread)
ENDIF (WIN32)
INCLUDE_DIRECTORIES(

View File

@@ -24,7 +24,7 @@ subject to the following restrictions:
#include "btBulletDynamicsCommon.h"
#include <stdio.h> //printf debugging
#include "Taru.mdl"
#include "Landscape.mdl"
#include "landscape.mdl"

View File

@@ -43,6 +43,7 @@ ELSE (WIN32)
# SET(CMAKE_BUILD_TYPE Debug)
# SET(CMAKE_CXX_FLAGS_DEBUG "-g")
INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR})
LINK_LIBRARIES(MultiThreadedDemo pthread)
# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY})
# TARGET_LINK_LIBRARIES(checker ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY})
ENDIF (WIN32)

View File

@@ -22,14 +22,19 @@ subject to the following restrictions:
#ifdef USE_PARALLEL_DISPATCHER
#include "../../Extras/BulletMultiThreaded/SpuGatheringCollisionDispatcher.h"
#ifdef WIN32
#endif //WIN32
#include "../../Extras/BulletMultiThreaded/PlatformDefinitions.h"
#ifdef USE_LIBSPE2
#include "../../Extras/BulletMultiThreaded/SpuLibspe2Support.h"
#elif defined (WIN32)
#include "../../Extras/BulletMultiThreaded/Win32ThreadSupport.h"
#include "../../Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h"
#elif defined (USE_PTHREADS)
#include "../../Extras/BulletMultiThreaded/PosixThreadSupport.h"
#include "../../Extras/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h"
#else
//other platforms run the parallel code sequentially (until pthread support or other parallel implementation is added)
#include "../../Extras/BulletMultiThreaded/SequentialThreadSupport.h"
@@ -44,7 +49,6 @@ subject to the following restrictions:
#endif//USE_PARALLEL_DISPATCHER
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btIDebugDraw.h"
@@ -222,10 +226,8 @@ void MultiThreadedDemo::displayCallback(void) {
void MultiThreadedDemo::initPhysics()
{
#ifdef USE_PARALLEL_DISPATCHER
#ifdef WIN32
m_threadSupportSolver = 0;
m_threadSupportCollision = 0;
#endif //
#endif
//#define USE_GROUND_PLANE 1
@@ -279,6 +281,12 @@ m_threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32Threa
program_handle = &spu_program;
#endif
SpuLibspe2Support* threadSupportCollision = new SpuLibspe2Support( program_handle, maxNumOutstandingTasks);
#elif defined (USE_PTHREADS)
PosixThreadSupport::ThreadConstructionInfo constructionInfo("collision",
processCollisionTask,
createCollisionLocalStoreMemory,
maxNumOutstandingTasks);
m_threadSupportCollision = new PosixThreadSupport(constructionInfo);
#else
SequentialThreadSupport::SequentialThreadConstructionInfo colCI("collision",processCollisionTask,createCollisionLocalStoreMemory);
@@ -315,7 +323,11 @@ m_threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32Threa
processSolverTask,
createSolverLocalStoreMemory,
maxNumOutstandingTasks));
#elif defined (USE_PTHREADS)
PosixThreadSupport::ThreadConstructionInfo solverConstructionInfo("solver", processSolverTask,
createSolverLocalStoreMemory, maxNumOutstandingTasks);
m_threadSupportSolver = new PosixThreadSupport(solverConstructionInfo);
#else
//for now use sequential version
SequentialThreadSupport::SequentialThreadConstructionInfo solverCI("solver",processSolverTask,createSolverLocalStoreMemory);
@@ -405,7 +417,6 @@ m_threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32Threa
void MultiThreadedDemo::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
@@ -436,12 +447,10 @@ void MultiThreadedDemo::exitPhysics()
//delete solver
delete m_solver;
#ifdef USE_PARALLEL_DISPATCHER
#ifdef WIN32
if (m_threadSupportSolver)
{
delete m_threadSupportSolver;
}
#endif
#endif
//delete broadphase
@@ -451,12 +460,10 @@ void MultiThreadedDemo::exitPhysics()
delete m_dispatcher;
#ifdef USE_PARALLEL_DISPATCHER
#ifdef WIN32
if (m_threadSupportCollision)
{
delete m_threadSupportCollision;
}
#endif
#endif
delete m_collisionConfiguration;

View File

@@ -12,7 +12,7 @@ subject to the following restrictions:
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <cstdio>
#include "MultiThreadedDemo.h"
#include "GlutStuff.h"
#include "GLDebugDrawer.h"
@@ -22,7 +22,6 @@ GLDebugDrawer gDebugDrawer;
int main(int argc,char** argv)
{
MultiThreadedDemo* demo = new MultiThreadedDemo();
demo->initPhysics();
@@ -33,4 +32,5 @@ int main(int argc,char** argv)
delete demo;
return EXIT_SUCCESS;
}

View File

@@ -16,6 +16,8 @@ ADD_LIBRARY(LibBulletMultiThreaded
Win32ThreadSupport.cpp
Win32ThreadSupport.h
PosixThreadSupport.cpp
PosixThreadSupport.h
SequentialThreadSupport.cpp
SequentialThreadSupport.h
SpuSampleTaskProcess.h

View File

@@ -1,7 +1,6 @@
#ifndef TYPE_DEFINITIONS_H
#define TYPE_DEFINITIONS_H
///This file provides some platform/compiler checks for common definitions
#ifdef WIN32
@@ -47,7 +46,7 @@ typedef union
#else
// posix system
#define USE_PTHREADS
#define USE_PTHREADS (1)
#ifdef USE_LIBSPE2
#include <stdio.h>

View File

@@ -0,0 +1,211 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <stdio.h>
#include "PosixThreadSupport.h"
#ifdef USE_PTHREADS
#include "SpuCollisionTaskProcess.h"
#include "SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h"
#define checkPThreadFunction(returnValue) \
if(0 != returnValue) { \
printf("PThread problem at line %i in file %s: %i\n", __LINE__, __FILE__, returnValue); \
}
// The number of threads should be equal to the number of available cores
// Todo: each worker should be linked to a single core, using SetThreadIdealProcessor.
// PosixThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication
// Setup and initialize SPU/CELL/Libspe2
PosixThreadSupport::PosixThreadSupport(ThreadConstructionInfo& threadConstructionInfo)
{
startThreads(threadConstructionInfo);
}
// cleanup/shutdown Libspe2
PosixThreadSupport::~PosixThreadSupport()
{
stopSPU();
}
// this semaphore will signal, if and how many threads are finished with their work
static sem_t mainSemaphore;
static void *threadFunction(void *argument)
{
PosixThreadSupport::btSpuStatus* status = (PosixThreadSupport::btSpuStatus*)argument;
while (1)
{
checkPThreadFunction(sem_wait(&status->startSemaphore));
void* userPtr = status->m_userPtr;
if (userPtr)
{
btAssert(status->m_status);
status->m_userThreadFunc(userPtr,status->m_lsMemory);
status->m_status = 2;
checkPThreadFunction(sem_post(&mainSemaphore));
status->threadUsed++;
} else {
//exit Thread
status->m_status = 3;
checkPThreadFunction(sem_post(&mainSemaphore));
printf("Thread with taskId %i exiting\n",status->m_taskId);
break;
}
}
printf("Thread TERMINATED\n");
return 0;
}
///send messages to SPUs
void PosixThreadSupport::sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t taskId)
{
/// gMidphaseSPU.sendRequest(CMD_GATHER_AND_PROCESS_PAIRLIST, (uint32_t) &taskDesc);
///we should spawn an SPU task here, and in 'waitForResponse' it should wait for response of the (one of) the first tasks that finished
switch (uiCommand)
{
case CMD_GATHER_AND_PROCESS_PAIRLIST:
{
btSpuStatus& spuStatus = m_activeSpuStatus[taskId];
btAssert(taskId >= 0);
btAssert(taskId < m_activeSpuStatus.size());
spuStatus.m_commandId = uiCommand;
spuStatus.m_status = 1;
spuStatus.m_userPtr = (void*)uiArgument0;
// fire event to start new task
checkPThreadFunction(sem_post(&spuStatus.startSemaphore));
break;
}
default:
{
///not implemented
btAssert(0);
}
};
}
///check for messages from SPUs
void PosixThreadSupport::waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1)
{
///We should wait for (one of) the first tasks to finish (or other SPU messages), and report its response
///A possible response can be 'yes, SPU handled it', or 'no, please do a PPU fallback'
btAssert(m_activeSpuStatus.size());
// wait for any of the threads to finish
checkPThreadFunction(sem_wait(&mainSemaphore));
// get at least one thread which has finished
size_t last = -1;
for(size_t t=0; t < m_activeSpuStatus.size(); ++t) {
if(2 == m_activeSpuStatus[t].m_status) {
last = t;
break;
}
}
btSpuStatus& spuStatus = m_activeSpuStatus[last];
btAssert(spuStatus.m_status > 1);
spuStatus.m_status = 0;
// need to find an active spu
btAssert(last >= 0);
*puiArgument0 = spuStatus.m_taskId;
*puiArgument1 = spuStatus.m_status;
}
void PosixThreadSupport::startThreads(ThreadConstructionInfo& threadConstructionInfo)
{
printf("%s creating %i threads.\n", __FUNCTION__, threadConstructionInfo.m_numThreads);
m_activeSpuStatus.resize(threadConstructionInfo.m_numThreads);
checkPThreadFunction(sem_init(&mainSemaphore, 0, 0));
for (int i=0;i < threadConstructionInfo.m_numThreads;i++)
{
printf("starting thread %d\n",i);
btSpuStatus& spuStatus = m_activeSpuStatus[i];
checkPThreadFunction(sem_init(&spuStatus.startSemaphore, 0, 0));
checkPThreadFunction(pthread_create(&spuStatus.thread, NULL, &threadFunction, (void*)&spuStatus));
spuStatus.m_userPtr=0;
spuStatus.m_taskId = i;
spuStatus.m_commandId = 0;
spuStatus.m_status = 0;
spuStatus.m_lsMemory = threadConstructionInfo.m_lsMemoryFunc();
spuStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc;
spuStatus.threadUsed = 0;
printf("started thread %d \n",i);
}
}
void PosixThreadSupport::startSPU()
{
}
///tell the task scheduler we are done with the SPU tasks
void PosixThreadSupport::stopSPU()
{
for(size_t t=0; t < m_activeSpuStatus.size(); ++t) {
btSpuStatus& spuStatus = m_activeSpuStatus[t];
printf("%s: Thread %i used: %ld\n", __FUNCTION__, t, spuStatus.threadUsed);
checkPThreadFunction(sem_destroy(&spuStatus.startSemaphore));
checkPThreadFunction(pthread_cancel(spuStatus.thread));
}
checkPThreadFunction(sem_destroy(&mainSemaphore));
m_activeSpuStatus.clear();
}
#endif // USE_PTHREADS

View File

@@ -0,0 +1,118 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <pthread.h>
#include <semaphore.h>
#include "LinearMath/btScalar.h"
#include "PlatformDefinitions.h"
#ifdef USE_PTHREADS //platform specific defines are defined in PlatformDefinitions.h
#ifndef POSIX_THREAD_SUPPORT_H
#define POSIX_THREAD_SUPPORT_H
#include "LinearMath/btAlignedObjectArray.h"
#include "btThreadSupportInterface.h"
typedef void (*PosixThreadFunc)(void* userPtr,void* lsMemory);
typedef void* (*PosixlsMemorySetupFunc)();
// PosixThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication
class PosixThreadSupport : public btThreadSupportInterface
{
public:
typedef enum sStatus {
STATUS_BUSY,
STATUS_READY,
STATUS_FINISHED
} Status;
// placeholder, until libspe2 support is there
struct btSpuStatus
{
uint32_t m_taskId;
uint32_t m_commandId;
uint32_t m_status;
PosixThreadFunc m_userThreadFunc;
void* m_userPtr; //for taskDesc etc
void* m_lsMemory; //initialized using PosixLocalStoreMemorySetupFunc
pthread_t thread;
sem_t startSemaphore;
unsigned long threadUsed;
};
private:
btAlignedObjectArray<btSpuStatus> m_activeSpuStatus;
public:
///Setup and initialize SPU/CELL/Libspe2
struct ThreadConstructionInfo
{
ThreadConstructionInfo(char* uniqueName,
PosixThreadFunc userThreadFunc,
PosixlsMemorySetupFunc lsMemoryFunc,
int numThreads=1,
int threadStackSize=65535
)
:m_uniqueName(uniqueName),
m_userThreadFunc(userThreadFunc),
m_lsMemoryFunc(lsMemoryFunc),
m_numThreads(numThreads),
m_threadStackSize(threadStackSize)
{
}
char* m_uniqueName;
PosixThreadFunc m_userThreadFunc;
PosixlsMemorySetupFunc m_lsMemoryFunc;
int m_numThreads;
int m_threadStackSize;
};
PosixThreadSupport(ThreadConstructionInfo& threadConstructionInfo);
///cleanup/shutdown Libspe2
virtual ~PosixThreadSupport();
void startThreads(ThreadConstructionInfo& threadInfo);
///send messages to SPUs
virtual void sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1);
///check for messages from SPUs
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1);
///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
virtual void startSPU();
///tell the task scheduler we are done with the SPU tasks
virtual void stopSPU();
};
#endif // POSIX_THREAD_SUPPORT_H
#endif // USE_PTHREADS

View File

@@ -18,7 +18,7 @@ subject to the following restrictions:
#define _14F9D17F_EAE8_4aba_B41C_292DB2AA70F3_
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/NarrowphaseCollision/btGjkEpa2.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
template <const int CELLSIZE>
struct btSparseSdf