17 #if BT_THREADSAFE && !defined(_WIN32)
30 #define _XOPEN_SOURCE 600
42 #if __cplusplus >= 201103L
46 int btGetNumHardwareThreads()
53 int btGetNumHardwareThreads()
70 ThreadFunc m_userThreadFunc;
75 sem_t* startSemaphore;
79 sem_t* m_mainSemaphore;
80 unsigned long threadUsed;
84 typedef unsigned long long UINT64;
88 sem_t* m_mainSemaphore;
90 UINT64 m_startedThreadsMask;
91 void startThreads(
const ConstructionInfo& threadInfo);
93 int waitForResponse();
96 btThreadSupportPosix(
const ConstructionInfo& threadConstructionInfo);
97 virtual ~btThreadSupportPosix();
112 #define checkPThreadFunction(returnValue) \
113 if (0 != returnValue) \
115 printf("PThread problem at line %i in file %s: %i %d\n", __LINE__, __FILE__, returnValue, errno); \
121 btThreadSupportPosix::btThreadSupportPosix(
const ConstructionInfo& threadConstructionInfo)
124 startThreads(threadConstructionInfo);
128 btThreadSupportPosix::~btThreadSupportPosix()
135 #if (defined(__APPLE__))
136 #define NAMED_SEMAPHORES
139 static sem_t* createSem(
const char* baseName)
141 static int semCount = 0;
142 #ifdef NAMED_SEMAPHORES
145 snprintf(name, 32,
"/%8.s-%4.d-%4.4d", baseName, getpid(), semCount++);
146 sem_t* tempSem = sem_open(name, O_CREAT, 0600, 0);
148 if (tempSem !=
reinterpret_cast<sem_t*
>(SEM_FAILED))
159 sem_t* tempSem =
new sem_t;
160 checkPThreadFunction(sem_init(tempSem, 0, 0));
165 static void destroySem(sem_t* semaphore)
167 #ifdef NAMED_SEMAPHORES
168 checkPThreadFunction(sem_close(semaphore));
170 checkPThreadFunction(sem_destroy(semaphore));
175 static void* threadFunction(
void* argument)
177 btThreadSupportPosix::btThreadStatus* status = (btThreadSupportPosix::btThreadStatus*)argument;
181 checkPThreadFunction(sem_wait(status->startSemaphore));
182 void* userPtr = status->m_userPtr;
187 status->m_userThreadFunc(userPtr);
188 status->m_cs->lock();
189 status->m_status = 2;
190 status->m_cs->unlock();
191 checkPThreadFunction(sem_post(status->m_mainSemaphore));
192 status->threadUsed++;
197 status->m_cs->lock();
198 status->m_status = 3;
199 status->m_cs->unlock();
200 checkPThreadFunction(sem_post(status->m_mainSemaphore));
209 void btThreadSupportPosix::runTask(
int threadIndex,
void* userData)
212 btThreadStatus& threadStatus = m_activeThreadStatus[threadIndex];
215 threadStatus.m_cs = m_cs;
216 threadStatus.m_commandId = 1;
217 threadStatus.m_status = 1;
218 threadStatus.m_userPtr = userData;
219 m_startedThreadsMask |= UINT64(1) << threadIndex;
222 checkPThreadFunction(sem_post(threadStatus.startSemaphore));
226 int btThreadSupportPosix::waitForResponse()
234 checkPThreadFunction(sem_wait(m_mainSemaphore));
238 for (
size_t t = 0;
t < size_t(m_activeThreadStatus.
size()); ++
t)
241 bool hasFinished = (2 == m_activeThreadStatus[
t].m_status);
250 btThreadStatus& threadStatus = m_activeThreadStatus[last];
252 btAssert(threadStatus.m_status > 1);
253 threadStatus.m_status = 0;
257 m_startedThreadsMask &= ~(UINT64(1) << last);
262 void btThreadSupportPosix::waitForAllTasks()
264 while (m_startedThreadsMask)
270 void btThreadSupportPosix::startThreads(
const ConstructionInfo& threadConstructionInfo)
272 m_numThreads = btGetNumHardwareThreads() - 1;
273 m_activeThreadStatus.
resize(m_numThreads);
274 m_startedThreadsMask = 0;
276 m_mainSemaphore = createSem(
"main");
279 for (
int i = 0; i < m_numThreads; i++)
281 btThreadStatus& threadStatus = m_activeThreadStatus[i];
282 threadStatus.startSemaphore = createSem(
"threadLocal");
283 threadStatus.m_userPtr = 0;
284 threadStatus.m_cs = m_cs;
285 threadStatus.m_taskId = i;
286 threadStatus.m_commandId = 0;
287 threadStatus.m_status = 0;
288 threadStatus.m_mainSemaphore = m_mainSemaphore;
289 threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc;
290 threadStatus.threadUsed = 0;
291 checkPThreadFunction(pthread_create(&threadStatus.thread,
NULL, &threadFunction, (
void*)&threadStatus));
297 void btThreadSupportPosix::stopThreads()
299 for (
size_t t = 0;
t < size_t(m_activeThreadStatus.
size()); ++
t)
301 btThreadStatus& threadStatus = m_activeThreadStatus[
t];
303 threadStatus.m_userPtr = 0;
304 checkPThreadFunction(sem_post(threadStatus.startSemaphore));
305 checkPThreadFunction(sem_wait(m_mainSemaphore));
307 checkPThreadFunction(pthread_join(threadStatus.thread, 0));
308 destroySem(threadStatus.startSemaphore);
310 destroySem(m_mainSemaphore);
311 m_activeThreadStatus.
clear();
316 pthread_mutex_t m_mutex;
319 btCriticalSectionPosix()
321 pthread_mutex_init(&m_mutex,
NULL);
323 virtual ~btCriticalSectionPosix()
325 pthread_mutex_destroy(&m_mutex);
330 pthread_mutex_lock(&m_mutex);
332 virtual void unlock()
334 pthread_mutex_unlock(&m_mutex);
340 return new btCriticalSectionPosix();
350 return new btThreadSupportPosix(info);
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
SIMD_FORCE_INLINE const T & btMin(const T &a, const T &b)
SIMD_FORCE_INLINE const T & btMax(const T &a, const T &b)
btSequentialImpulseConstraintSolverMt int btPersistentManifold int btTypedConstraint int const btContactSolverInfo btIDebugDraw *debugDrawer BT_OVERRIDE
const unsigned int BT_MAX_THREAD_COUNT
SIMD_FORCE_INLINE void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0),...
SIMD_FORCE_INLINE int size() const
return the number of elements in the array
SIMD_FORCE_INLINE void resize(int newsize, const T &fillData=T())
virtual int getCacheFriendlyNumThreads() const =0
virtual int getLogicalToPhysicalCoreRatio() const =0
virtual void waitForAllTasks()=0
virtual void runTask(int threadIndex, void *userData)=0
virtual btCriticalSection * createCriticalSection()=0
virtual int getNumWorkerThreads() const =0
static btThreadSupportInterface * create(const ConstructionInfo &info)
virtual void deleteCriticalSection(btCriticalSection *criticalSection)=0