From 2f0fd80c9cf074d8ba60d973412314897656f764 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Thu, 18 Jul 2013 21:18:09 -0700 Subject: [PATCH] enable poxix MultiThreading sample under Linux --- btgui/MultiThreading/b3PosixThreadSupport.cpp | 201 ++++++++++-------- btgui/MultiThreading/b3PosixThreadSupport.h | 83 ++++---- .../b3SequentialThreadSupport.cpp | 179 ---------------- .../b3SequentialThreadSupport.h | 100 --------- .../MultiThreading/b3ThreadSupportInterface.h | 7 +- btgui/MultiThreading/main.cpp | 42 ++-- btgui/MultiThreading/premake4.lua | 20 +- build3/premake4.lua | 1 + 8 files changed, 193 insertions(+), 440 deletions(-) delete mode 100644 btgui/MultiThreading/b3SequentialThreadSupport.cpp delete mode 100644 btgui/MultiThreading/b3SequentialThreadSupport.h diff --git a/btgui/MultiThreading/b3PosixThreadSupport.cpp b/btgui/MultiThreading/b3PosixThreadSupport.cpp index 81c0cf86d..eeca1a261 100644 --- a/btgui/MultiThreading/b3PosixThreadSupport.cpp +++ b/btgui/MultiThreading/b3PosixThreadSupport.cpp @@ -4,8 +4,8 @@ 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, +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. @@ -14,13 +14,10 @@ subject to the following restrictions: */ #include -#include "PosixThreadSupport.h" -#ifdef USE_PTHREADS +#include "b3PosixThreadSupport.h" #include #include -#include "SpuCollisionTaskProcess.h" -#include "SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" #define checkPThreadFunction(returnValue) \ if(0 != returnValue) { \ @@ -30,17 +27,16 @@ subject to the following restrictions: // 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) + +b3PosixThreadSupport::b3PosixThreadSupport(ThreadConstructionInfo& threadConstructionInfo) { startThreads(threadConstructionInfo); } // cleanup/shutdown Libspe2 -PosixThreadSupport::~PosixThreadSupport() +b3PosixThreadSupport::~b3PosixThreadSupport() { - stopSPU(); + stopThreads(); } #if (defined (__APPLE__)) @@ -56,7 +52,7 @@ static sem_t* createSem(const char* baseName) #ifdef NAMED_SEMAPHORES /// Named semaphore begin char name[32]; - snprintf(name, 32, "/%s-%d-%4.4d", baseName, getpid(), semCount++); + snprintf(name, 32, "/%s-%d-%4.4d", baseName, getpid(), semCount++); sem_t* tempSem = sem_open(name, O_CREAT, 0600, 0); if (tempSem != reinterpret_cast(SEM_FAILED)) @@ -83,24 +79,24 @@ static void destroySem(sem_t* semaphore) #else checkPThreadFunction(sem_destroy(semaphore)); delete semaphore; -#endif +#endif } -static void *threadFunction(void *argument) +static void *threadFunction(void *argument) { - PosixThreadSupport::btSpuStatus* status = (PosixThreadSupport::btSpuStatus*)argument; + b3PosixThreadSupport::b3ThreadStatus* status = (b3PosixThreadSupport::b3ThreadStatus*)argument; + - while (1) { checkPThreadFunction(sem_wait(status->startSemaphore)); - + void* userPtr = status->m_userPtr; if (userPtr) { - btAssert(status->m_status); + b3Assert(status->m_status); status->m_userThreadFunc(userPtr,status->m_lsMemory); status->m_status = 2; checkPThreadFunction(sem_post(mainSemaphore)); @@ -112,7 +108,7 @@ static void *threadFunction(void *argument) printf("Thread with taskId %i exiting\n",status->m_taskId); break; } - + } printf("Thread TERMINATED\n"); @@ -121,21 +117,21 @@ static void *threadFunction(void *argument) } ///send messages to SPUs -void PosixThreadSupport::sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t taskId) +void b3PosixThreadSupport::sendRequest(int uiCommand, void* uiArgument0, int taskId) { - /// gMidphaseSPU.sendRequest(CMD_GATHER_AND_PROCESS_PAIRLIST, (uint32_t) &taskDesc); - + /// gMidphaseSPU.sendRequest(CMD_GATHER_AND_PROCESS_PAIRLIST, (int) &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: + case B3_THREAD_SCHEDULE_TASK: { - btSpuStatus& spuStatus = m_activeSpuStatus[taskId]; - btAssert(taskId >= 0); - btAssert(taskId < m_activeSpuStatus.size()); + b3ThreadStatus& spuStatus = m_activeThreadStatus[taskId]; + b3Assert(taskId >= 0); + b3Assert(taskId < m_activeThreadStatus.size()); spuStatus.m_commandId = uiCommand; spuStatus.m_status = 1; @@ -148,7 +144,7 @@ void PosixThreadSupport::sendRequest(uint32_t uiCommand, ppu_address_t uiArgumen default: { ///not implemented - btAssert(0); + b3Assert(0); } }; @@ -156,37 +152,72 @@ void PosixThreadSupport::sendRequest(uint32_t uiCommand, ppu_address_t uiArgumen } - -///check for messages from SPUs -void PosixThreadSupport::waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1) +///non-blocking test if a task is completed. First implement all versions, and then enable this API +bool b3PosixThreadSupport::isTaskCompleted(int *puiArgument0, int *puiArgument1, int timeOutInMilliseconds) { - ///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()); + b3Assert(m_activeThreadStatus.size()); // wait for any of the threads to finish - checkPThreadFunction(sem_wait(mainSemaphore)); - - // get at least one thread which has finished + int result = sem_trywait(mainSemaphore); + if (result==0) + { + // get at least one thread which has finished size_t last = -1; - - for(size_t t=0; t < size_t(m_activeSpuStatus.size()); ++t) { - if(2 == m_activeSpuStatus[t].m_status) { + + for(size_t t=0; t < size_t(m_activeThreadStatus.size()); ++t) { + if(2 == m_activeThreadStatus[t].m_status) { last = t; break; } } - btSpuStatus& spuStatus = m_activeSpuStatus[last]; + b3ThreadStatus& spuStatus = m_activeThreadStatus[last]; - btAssert(spuStatus.m_status > 1); + b3Assert(spuStatus.m_status > 1); + spuStatus.m_status = 0; + + // need to find an active spu + b3Assert(last >= 0); + + *puiArgument0 = spuStatus.m_taskId; + *puiArgument1 = spuStatus.m_status; + return true; + } + return false; +} + + +///check for messages from SPUs +void b3PosixThreadSupport::waitForResponse( int *puiArgument0, 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' + + + b3Assert(m_activeThreadStatus.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 < size_t(m_activeThreadStatus.size()); ++t) { + if(2 == m_activeThreadStatus[t].m_status) { + last = t; + break; + } + } + + b3ThreadStatus& spuStatus = m_activeThreadStatus[last]; + + b3Assert(spuStatus.m_status > 1); spuStatus.m_status = 0; // need to find an active spu - btAssert(last >= 0); + b3Assert(last >= 0); *puiArgument0 = spuStatus.m_taskId; *puiArgument1 = spuStatus.m_status; @@ -194,22 +225,22 @@ void PosixThreadSupport::waitForResponse(unsigned int *puiArgument0, unsigned in -void PosixThreadSupport::startThreads(ThreadConstructionInfo& threadConstructionInfo) +void b3PosixThreadSupport::startThreads(ThreadConstructionInfo& threadConstructionInfo) { printf("%s creating %i threads.\n", __FUNCTION__, threadConstructionInfo.m_numThreads); - m_activeSpuStatus.resize(threadConstructionInfo.m_numThreads); - - mainSemaphore = createSem("main"); + m_activeThreadStatus.resize(threadConstructionInfo.m_numThreads); + + mainSemaphore = createSem("main"); //checkPThreadFunction(sem_wait(mainSemaphore)); - + for (int i=0;i < threadConstructionInfo.m_numThreads;i++) { printf("starting thread %d\n",i); - btSpuStatus& spuStatus = m_activeSpuStatus[i]; + b3ThreadStatus& spuStatus = m_activeThreadStatus[i]; + + spuStatus.startSemaphore = createSem("threadLocal"); - spuStatus.startSemaphore = createSem("threadLocal"); - checkPThreadFunction(pthread_create(&spuStatus.thread, NULL, &threadFunction, (void*)&spuStatus)); spuStatus.m_userPtr=0; @@ -222,29 +253,26 @@ void PosixThreadSupport::startThreads(ThreadConstructionInfo& threadConstruction 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() +void b3PosixThreadSupport::stopThreads() { - for(size_t t=0; t < size_t(m_activeSpuStatus.size()); ++t) + for(size_t t=0; t < size_t(m_activeThreadStatus.size()); ++t) { - btSpuStatus& spuStatus = m_activeSpuStatus[t]; + b3ThreadStatus& spuStatus = m_activeThreadStatus[t]; printf("%s: Thread %i used: %ld\n", __FUNCTION__, int(t), spuStatus.threadUsed); - spuStatus.m_userPtr = 0; + spuStatus.m_userPtr = 0; checkPThreadFunction(sem_post(spuStatus.startSemaphore)); checkPThreadFunction(sem_wait(mainSemaphore)); - printf("destroy semaphore\n"); + printf("destroy semaphore\n"); destroySem(spuStatus.startSemaphore); printf("semaphore destroyed\n"); checkPThreadFunction(pthread_join(spuStatus.thread,0)); @@ -253,25 +281,25 @@ void PosixThreadSupport::stopSPU() printf("destroy main semaphore\n"); destroySem(mainSemaphore); printf("main semaphore destroyed\n"); - m_activeSpuStatus.clear(); + m_activeThreadStatus.clear(); } -class PosixCriticalSection : public btCriticalSection +class b3PosixCriticalSection : public b3CriticalSection { pthread_mutex_t m_mutex; - + public: - PosixCriticalSection() + b3PosixCriticalSection() { pthread_mutex_init(&m_mutex, NULL); } - virtual ~PosixCriticalSection() + virtual ~b3PosixCriticalSection() { pthread_mutex_destroy(&m_mutex); } - - ATTRIBUTE_ALIGNED16(unsigned int mCommonBuff[32]); - + + B3_ATTRIBUTE_ALIGNED16(unsigned int mCommonBuff[32]); + virtual unsigned int getSharedParam(int i) { return mCommonBuff[i]; @@ -280,7 +308,7 @@ public: { mCommonBuff[i] = p; } - + virtual void lock() { pthread_mutex_lock(&m_mutex); @@ -294,7 +322,7 @@ public: #if defined(_POSIX_BARRIERS) && (_POSIX_BARRIERS - 20012L) >= 0 /* OK to use barriers on this platform */ -class PosixBarrier : public btBarrier +class PosixBarrier : public b3Barrier { pthread_barrier_t m_barr; int m_numThreads; @@ -304,7 +332,7 @@ public: virtual ~PosixBarrier() { pthread_barrier_destroy(&m_barr); } - + virtual void sync() { int rc = pthread_barrier_wait(&m_barr); @@ -318,7 +346,7 @@ public: { int result = pthread_barrier_init(&m_barr, NULL, numThreads); m_numThreads = numThreads; - btAssert(result==0); + b3Assert(result==0); } virtual int getMaxCount() { @@ -327,20 +355,20 @@ public: }; #else /* Not OK to use barriers on this platform - insert alternate code here */ -class PosixBarrier : public btBarrier +class PosixBarrier : public btBarrier { pthread_mutex_t m_mutex; pthread_cond_t m_cond; - + int m_numThreads; int m_called; - + public: PosixBarrier() :m_numThreads(0) { } - virtual ~PosixBarrier() + virtual ~PosixBarrier() { if (m_numThreads>0) { @@ -348,9 +376,9 @@ public: pthread_cond_destroy(&m_cond); } } - + virtual void sync() - { + { pthread_mutex_lock(&m_mutex); m_called++; if (m_called == m_numThreads) { @@ -360,7 +388,7 @@ public: pthread_cond_wait(&m_cond,&m_mutex); } pthread_mutex_unlock(&m_mutex); - + } virtual void setMaxCount(int numThreads) { @@ -384,26 +412,25 @@ public: -btBarrier* PosixThreadSupport::createBarrier() +b3Barrier* b3PosixThreadSupport::createBarrier() { PosixBarrier* barrier = new PosixBarrier(); barrier->setMaxCount(getNumTasks()); return barrier; } -btCriticalSection* PosixThreadSupport::createCriticalSection() +b3CriticalSection* b3PosixThreadSupport::createCriticalSection() { - return new PosixCriticalSection(); + return new b3PosixCriticalSection(); } -void PosixThreadSupport::deleteBarrier(btBarrier* barrier) +void b3PosixThreadSupport::deleteBarrier(b3Barrier* barrier) { delete barrier; } -void PosixThreadSupport::deleteCriticalSection(btCriticalSection* cs) +void b3PosixThreadSupport::deleteCriticalSection(b3CriticalSection* cs) { delete cs; } -#endif // USE_PTHREADS diff --git a/btgui/MultiThreading/b3PosixThreadSupport.h b/btgui/MultiThreading/b3PosixThreadSupport.h index bf7578f51..17dde8d60 100644 --- a/btgui/MultiThreading/b3PosixThreadSupport.h +++ b/btgui/MultiThreading/b3PosixThreadSupport.h @@ -4,8 +4,8 @@ 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, +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. @@ -13,14 +13,12 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#ifndef BT_POSIX_THREAD_SUPPORT_H -#define BT_POSIX_THREAD_SUPPORT_H +#ifndef B3_POSIX_THREAD_SUPPORT_H +#define B3_POSIX_THREAD_SUPPORT_H -#include "LinearMath/btScalar.h" -#include "PlatformDefinitions.h" +#include "Bullet3Common/b3Scalar.h" -#ifdef USE_PTHREADS //platform specifc defines are defined in PlatformDefinitions.h #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 //for definition of pthread_barrier_t, see http://pages.cs.wisc.edu/~travitch/pthreads_primer.html @@ -30,16 +28,16 @@ subject to the following restrictions: -#include "LinearMath/btAlignedObjectArray.h" +#include "Bullet3Common/b3AlignedObjectArray.h" -#include "btThreadSupportInterface.h" +#include "b3ThreadSupportInterface.h" -typedef void (*PosixThreadFunc)(void* userPtr,void* lsMemory); -typedef void* (*PosixlsMemorySetupFunc)(); +typedef void (*b3PosixThreadFunc)(void* userPtr,void* lsMemory); +typedef void* (*b3PosixlsMemorySetupFunc)(); -// PosixThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication -class PosixThreadSupport : public btThreadSupportInterface +// b3PosixThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication +class b3PosixThreadSupport : public b3ThreadSupportInterface { public: typedef enum sStatus { @@ -49,13 +47,13 @@ public: } Status; // placeholder, until libspe2 support is there - struct btSpuStatus + struct b3ThreadStatus { - uint32_t m_taskId; - uint32_t m_commandId; - uint32_t m_status; + int m_taskId; + int m_commandId; + int m_status; - PosixThreadFunc m_userThreadFunc; + b3PosixThreadFunc m_userThreadFunc; void* m_userPtr; //for taskDesc etc void* m_lsMemory; //initialized using PosixLocalStoreMemorySetupFunc @@ -66,17 +64,17 @@ public: }; private: - btAlignedObjectArray m_activeSpuStatus; + b3AlignedObjectArray m_activeThreadStatus; public: ///Setup and initialize SPU/CELL/Libspe2 - + struct ThreadConstructionInfo { ThreadConstructionInfo(const char* uniqueName, - PosixThreadFunc userThreadFunc, - PosixlsMemorySetupFunc lsMemoryFunc, + b3PosixThreadFunc userThreadFunc, + b3PosixlsMemorySetupFunc lsMemoryFunc, int numThreads=1, int threadStackSize=65535 ) @@ -90,58 +88,57 @@ public: } const char* m_uniqueName; - PosixThreadFunc m_userThreadFunc; - PosixlsMemorySetupFunc m_lsMemoryFunc; + b3PosixThreadFunc m_userThreadFunc; + b3PosixlsMemorySetupFunc m_lsMemoryFunc; int m_numThreads; int m_threadStackSize; }; - PosixThreadSupport(ThreadConstructionInfo& threadConstructionInfo); + b3PosixThreadSupport(ThreadConstructionInfo& threadConstructionInfo); ///cleanup/shutdown Libspe2 - virtual ~PosixThreadSupport(); + virtual ~b3PosixThreadSupport(); void startThreads(ThreadConstructionInfo& threadInfo); -///send messages to SPUs - virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1); + virtual void sendRequest(int uiCommand, void* uiArgument0, int uiArgument1); -///check for messages from SPUs - virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1); + virtual void waitForResponse(int *puiArgument0, 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(); + virtual void stopThreads(); virtual void setNumTasks(int numTasks) {} virtual int getNumTasks() const { - return m_activeSpuStatus.size(); + return m_activeThreadStatus.size(); } - virtual btBarrier* createBarrier(); + ///non-blocking test if a task is completed. First implement all versions, and then enable this API + virtual bool isTaskCompleted(int *puiArgument0, int *puiArgument1, int timeOutInMilliseconds); - virtual btCriticalSection* createCriticalSection(); - virtual void deleteBarrier(btBarrier* barrier); + virtual b3Barrier* createBarrier(); + + virtual b3CriticalSection* createCriticalSection(); + + virtual void deleteBarrier(b3Barrier* barrier); + + virtual void deleteCriticalSection(b3CriticalSection* criticalSection); + - virtual void deleteCriticalSection(btCriticalSection* criticalSection); - - virtual void* getThreadLocalMemory(int taskId) { - return m_activeSpuStatus[taskId].m_lsMemory; + return m_activeThreadStatus[taskId].m_lsMemory; } }; -#endif // USE_PTHREADS -#endif // BT_POSIX_THREAD_SUPPORT_H +#endif // B3_POSIX_THREAD_SUPPORT_H diff --git a/btgui/MultiThreading/b3SequentialThreadSupport.cpp b/btgui/MultiThreading/b3SequentialThreadSupport.cpp deleted file mode 100644 index defcc2d49..000000000 --- a/btgui/MultiThreading/b3SequentialThreadSupport.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* -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 "b3SequentialThreadSupport.h" - - - -b3SequentialThreadSupport::b3SequentialThreadSupport(SequentialThreadConstructionInfo& threadConstructionInfo) -{ - startThreads(threadConstructionInfo); -} - -///cleanup/shutdown Libspe2 -b3SequentialThreadSupport::~b3SequentialThreadSupport() -{ - stopThreads(); -} - -#include - -///send messages to SPUs -void b3SequentialThreadSupport::sendRequest(int uiCommand, void* uiArgument0, int taskId) -{ - switch (uiCommand) - { - case B3_THREAD_SCHEDULE_TASK: - { - btSpuStatus& spuStatus = m_activeSpuStatus[0]; - spuStatus.m_userPtr=(void*)uiArgument0; - spuStatus.m_userThreadFunc(spuStatus.m_userPtr,spuStatus.m_lsMemory); - } - break; - default: - { - ///not implemented - b3Assert(0 && "Not implemented"); - } - - }; - - -} - -///check for messages from SPUs -void b3SequentialThreadSupport::waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1) -{ - b3Assert(m_activeSpuStatus.size()); - btSpuStatus& spuStatus = m_activeSpuStatus[0]; - *puiArgument0 = spuStatus.m_taskId; - *puiArgument1 = spuStatus.m_status; -} - -void b3SequentialThreadSupport::startThreads(SequentialThreadConstructionInfo& threadConstructionInfo) -{ - m_activeSpuStatus.resize(1); - printf("STS: Not starting any threads\n"); - btSpuStatus& spuStatus = m_activeSpuStatus[0]; - spuStatus.m_userPtr = 0; - spuStatus.m_taskId = 0; - spuStatus.m_commandId = 0; - spuStatus.m_status = 0; - spuStatus.m_lsMemory = threadConstructionInfo.m_lsMemoryFunc(); - spuStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc; - printf("STS: Created local store at %p for task %s\n", spuStatus.m_lsMemory, threadConstructionInfo.m_uniqueName); -} - -void b3SequentialThreadSupport::startThreads() -{ -} - -void b3SequentialThreadSupport::stopThreads() -{ - m_activeSpuStatus.clear(); -} - -void b3SequentialThreadSupport::setNumTasks(int numTasks) -{ - printf("b3SequentialThreadSupport::setNumTasks(%d) is not implemented and has no effect\n",numTasks); -} - - - - -class btDummyBarrier : public b3Barrier -{ -private: - -public: - btDummyBarrier() - { - } - - virtual ~btDummyBarrier() - { - } - - void sync() - { - } - - virtual void setMaxCount(int n) {} - virtual int getMaxCount() {return 1;} -}; - -class btDummyCriticalSection : public b3CriticalSection -{ - -public: - btDummyCriticalSection() - { - } - - virtual ~btDummyCriticalSection() - { - } - - unsigned int getSharedParam(int i) - { - b3Assert(i>=0&&i<31); - return mCommonBuff[i+1]; - } - - void setSharedParam(int i,unsigned int p) - { - b3Assert(i>=0&&i<31); - mCommonBuff[i+1] = p; - } - - void lock() - { - mCommonBuff[0] = 1; - } - - void unlock() - { - mCommonBuff[0] = 0; - } -}; - - - - -b3Barrier* b3SequentialThreadSupport::createBarrier() -{ - return new btDummyBarrier(); -} - -b3CriticalSection* b3SequentialThreadSupport::createCriticalSection() -{ - return new btDummyCriticalSection(); - -} - -void b3SequentialThreadSupport::deleteBarrier(b3Barrier* barrier) -{ - delete barrier; -} - -void b3SequentialThreadSupport::deleteCriticalSection(b3CriticalSection* criticalSection) -{ - delete criticalSection; -} - - - - - diff --git a/btgui/MultiThreading/b3SequentialThreadSupport.h b/btgui/MultiThreading/b3SequentialThreadSupport.h deleted file mode 100644 index bdc1cd5be..000000000 --- a/btgui/MultiThreading/b3SequentialThreadSupport.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -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 "Bullet3Common/b3Scalar.h" - - - -#ifndef B3_SEQUENTIAL_THREAD_SUPPORT_H -#define B3_SEQUENTIAL_THREAD_SUPPORT_H - -#include "Bullet3Common/b3AlignedObjectArray.h" - -#include "b3ThreadSupportInterface.h" - -typedef void (*SequentialThreadFunc)(void* userPtr,void* lsMemory); -typedef void* (*SequentiallsMemorySetupFunc)(); - - - -///The b3SequentialThreadSupport is a portable non-parallel implementation of the btThreadSupportInterface -///This is useful for debugging and porting SPU Tasks to other platforms. -class b3SequentialThreadSupport : public b3ThreadSupportInterface -{ -public: - struct btSpuStatus - { - int m_taskId; - int m_commandId; - int m_status; - - SequentialThreadFunc m_userThreadFunc; - - void* m_userPtr; //for taskDesc etc - void* m_lsMemory; //initialized using SequentiallsMemorySetupFunc - }; -private: - b3AlignedObjectArray m_activeSpuStatus; - b3AlignedObjectArray m_completeHandles; -public: - struct SequentialThreadConstructionInfo - { - SequentialThreadConstructionInfo (const char* uniqueName, - SequentialThreadFunc userThreadFunc, - SequentiallsMemorySetupFunc lsMemoryFunc - ) - :m_uniqueName(uniqueName), - m_userThreadFunc(userThreadFunc), - m_lsMemoryFunc(lsMemoryFunc) - { - - } - - const char* m_uniqueName; - SequentialThreadFunc m_userThreadFunc; - SequentiallsMemorySetupFunc m_lsMemoryFunc; - }; - - b3SequentialThreadSupport(SequentialThreadConstructionInfo& threadConstructionInfo); - virtual ~b3SequentialThreadSupport(); - void startThreads(SequentialThreadConstructionInfo& threadInfo); -///send messages to SPUs - virtual void sendRequest(int uiCommand, void* uiArgument0, int 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 startThreads(); -///tell the task scheduler we are done with the SPU tasks - virtual void stopThreads(); - - virtual void setNumTasks(int numTasks); - - virtual int getNumTasks() const - { - return 1; - } - virtual b3Barrier* createBarrier(); - - virtual b3CriticalSection* createCriticalSection(); - - virtual void deleteBarrier(b3Barrier* barrier); - - virtual void deleteCriticalSection(b3CriticalSection* criticalSection); - - -}; - -#endif //B3_SEQUENTIAL_THREAD_SUPPORT_H - diff --git a/btgui/MultiThreading/b3ThreadSupportInterface.h b/btgui/MultiThreading/b3ThreadSupportInterface.h index 6706bd799..d53209abd 100644 --- a/btgui/MultiThreading/b3ThreadSupportInterface.h +++ b/btgui/MultiThreading/b3ThreadSupportInterface.h @@ -4,8 +4,8 @@ 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, +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. @@ -66,7 +66,6 @@ public: ///non-blocking test if a task is completed. First implement all versions, and then enable this API virtual bool isTaskCompleted(int *puiArgument0, int *puiArgument1, int timeOutInMilliseconds)=0; - virtual void startThreads() =0; virtual void stopThreads()=0; @@ -82,7 +81,7 @@ public: virtual void deleteBarrier(b3Barrier* barrier)=0; virtual void deleteCriticalSection(b3CriticalSection* criticalSection)=0; - + virtual void* getThreadLocalMemory(int taskId) { return 0; } }; diff --git a/btgui/MultiThreading/main.cpp b/btgui/MultiThreading/main.cpp index cc12b8b68..88d0d11be 100644 --- a/btgui/MultiThreading/main.cpp +++ b/btgui/MultiThreading/main.cpp @@ -4,8 +4,8 @@ Copyright (c) 2010 Erwin Coumans http://bulletphysics.org 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, +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. @@ -17,7 +17,7 @@ subject to the following restrictions: /// You can start threads and perform a blocking wait for completion /// Under Windows it uses Win32 Threads. On Mac and Linux it uses pthreads. On PlayStation 3 Cell SPU it uses SPURS. -/// June 2010 +/// June 2010 /// New: critical section/barriers and non-blocking pollingn for completion, currently Windows only void SampleThreadFunc(void* userPtr,void* lsMemory); @@ -26,20 +26,19 @@ void* SamplelsMemoryFunc(); #include //#include "BulletMultiThreaded/PlatformDefinitions.h" -#ifdef USE_PTHREADS -//#ifdef __APPLE__ -#include "BulletMultiThreaded/PosixThreadSupport.h" +#ifndef _WIN32 +#include "b3PosixThreadSupport.h" b3ThreadSupportInterface* createThreadSupport(int numThreads) { - PosixThreadSupport::ThreadConstructionInfo constructionInfo("testThreads", + b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("testThreads", SampleThreadFunc, SamplelsMemoryFunc, numThreads); - b3ThreadSupportInterface* threadSupport = new PosixThreadSupport(constructionInfo); - + b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo); + return threadSupport; - + } @@ -51,12 +50,12 @@ b3ThreadSupportInterface* createThreadSupport(int numThreads) b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("testThreads",SampleThreadFunc,SamplelsMemoryFunc,numThreads); b3Win32ThreadSupport* threadSupport = new b3Win32ThreadSupport(threadConstructionInfo); return threadSupport; - -} +} #endif + struct SampleArgs { SampleArgs() @@ -122,8 +121,7 @@ int main(int argc,char** argv) b3ThreadSupportInterface* threadSupport = createThreadSupport(numThreads); - - threadSupport->startThreads(); + for (int i=0;igetNumTasks();i++) { @@ -131,13 +129,13 @@ int main(int argc,char** argv) b3Assert(storage); storage->threadId = i; } - + SampleArgs args; args.m_cs = threadSupport->createCriticalSection(); args.m_cs->setSharedParam(0,100); - + int arg0,arg1; int i; for (i=0;isendRequest(B3_THREAD_SCHEDULE_TASK, (void*) &args, i); } - bool blockingWait =true; + bool blockingWait =false; if (blockingWait) { for (i=0;iisTaskCompleted(&arg0,&arg1,0)) + if (threadSupport->isTaskCompleted(&arg0,&arg1,0)) { numActiveThreads--; printf("numActiveThreads = %d\n",numActiveThreads); } else { - printf("polling\n"); +// printf("polling.."); } }; -#else - btAssert(0); - printf("non-blocking wait is not supported on this platform\n"); - exit(0); -#endif } printf("stopping threads\n"); diff --git a/btgui/MultiThreading/premake4.lua b/btgui/MultiThreading/premake4.lua index 3ed370ffd..5ed0339b5 100644 --- a/btgui/MultiThreading/premake4.lua +++ b/btgui/MultiThreading/premake4.lua @@ -17,19 +17,35 @@ files { - "**.cpp", - "**.h" + "b3ThreadSupportInterface.cpp", + "main.cpp", + "b3ThreadSupportInterface.h" } if os.is("Windows") then + + files { + "b3Win32ThreadSupport.cpp", + "b3Win32ThreadSupport.h" + } --links {"winmm"} --defines {"__WINDOWS_MM__", "WIN32"} end if os.is("Linux") then + files { + "b3PosixThreadSupport.cpp", + "b3PosixThreadSupport.h" + } + links {"pthread"} end if os.is("MacOSX") then + files { + "b3PosixThreadSupport.cpp", + "b3PosixThreadSupport.h" + } + links {"pthread"} --links{"CoreAudio.framework", "coreMIDI.framework", "Cocoa.framework"} --defines {"__MACOSX_CORE__"} diff --git a/build3/premake4.lua b/build3/premake4.lua index f25f6eb5d..a810c1b79 100644 --- a/build3/premake4.lua +++ b/build3/premake4.lua @@ -100,6 +100,7 @@ language "C++" include "../Demos3/Wavefront" + include "../btgui/MultiThreading" if not _OPTIONS["ios"] then -- include "../demo/gpudemo"