MultiThreadingExample.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #include "MultiThreadingExample.h"
  2. #include "../CommonInterfaces/CommonGraphicsAppInterface.h"
  3. #include "../CommonInterfaces/CommonRenderInterface.h"
  4. #include "../CommonInterfaces/CommonExampleInterface.h"
  5. #include "LinearMath/btTransform.h"
  6. #include "../CommonInterfaces/CommonGUIHelperInterface.h"
  7. #include "../RenderingExamples/TimeSeriesCanvas.h"
  8. #include "stb_image/stb_image.h"
  9. #include "Bullet3Common/b3Quaternion.h"
  10. #include "Bullet3Common/b3Matrix3x3.h"
  11. #include "../CommonInterfaces/CommonParameterInterface.h"
  12. #include "LinearMath/btAlignedObjectArray.h"
  13. #define stdvector btAlignedObjectArray
  14. #define MAGIC_RESET_NUMBER 64738
  15. void SampleThreadFunc(void* userPtr,void* lsMemory);
  16. void* SamplelsMemoryFunc();
  17. #include <stdio.h>
  18. //#include "BulletMultiThreaded/PlatformDefinitions.h"
  19. #ifndef _WIN32
  20. #include "b3PosixThreadSupport.h"
  21. b3ThreadSupportInterface* createThreadSupport(int numThreads)
  22. {
  23. b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("testThreads",
  24. SampleThreadFunc,
  25. SamplelsMemoryFunc,
  26. numThreads);
  27. b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo);
  28. return threadSupport;
  29. }
  30. #elif defined( _WIN32)
  31. #include "b3Win32ThreadSupport.h"
  32. b3ThreadSupportInterface* createThreadSupport(int numThreads)
  33. {
  34. b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("testThreads",SampleThreadFunc,SamplelsMemoryFunc,numThreads);
  35. b3Win32ThreadSupport* threadSupport = new b3Win32ThreadSupport(threadConstructionInfo);
  36. return threadSupport;
  37. }
  38. #endif
  39. struct SampleJobInterface
  40. {
  41. virtual void executeJob(int threadIndex)=0;
  42. };
  43. struct SampleJob1 : public SampleJobInterface
  44. {
  45. float m_fakeWork;
  46. int m_jobId;
  47. SampleJob1(int jobId)
  48. :m_fakeWork(0),
  49. m_jobId(jobId)
  50. {
  51. }
  52. virtual void executeJob(int threadIndex)
  53. {
  54. printf("start SampleJob1 %d using threadIndex %d\n",m_jobId,threadIndex);
  55. //do some fake work
  56. for (int i=0;i<1000000;i++)
  57. m_fakeWork = b3Scalar(1.21)*m_fakeWork;
  58. printf("finished SampleJob1 %d using threadIndex %d\n",m_jobId,threadIndex);
  59. }
  60. };
  61. struct SampleArgs
  62. {
  63. SampleArgs()
  64. {
  65. }
  66. b3CriticalSection* m_cs;
  67. btAlignedObjectArray<SampleJobInterface*> m_jobQueue;
  68. void submitJob(SampleJobInterface* job)
  69. {
  70. m_cs->lock();
  71. m_jobQueue.push_back(job);
  72. m_cs->unlock();
  73. }
  74. SampleJobInterface* consumeJob()
  75. {
  76. SampleJobInterface* job = 0;
  77. m_cs->lock();
  78. int sz = m_jobQueue.size();
  79. if (sz)
  80. {
  81. job = m_jobQueue[sz-1];
  82. m_jobQueue.pop_back();
  83. }
  84. m_cs->unlock();
  85. return job;
  86. }
  87. };
  88. SampleArgs args;
  89. struct SampleThreadLocalStorage
  90. {
  91. int threadId;
  92. };
  93. void SampleThreadFunc(void* userPtr,void* lsMemory)
  94. {
  95. printf("thread started\n");
  96. SampleThreadLocalStorage* localStorage = (SampleThreadLocalStorage*) lsMemory;
  97. SampleArgs* args = (SampleArgs*) userPtr;
  98. bool requestExit = false;
  99. while (!requestExit)
  100. {
  101. SampleJobInterface* job = args->consumeJob();
  102. if (job)
  103. {
  104. job->executeJob(localStorage->threadId);
  105. }
  106. args->m_cs->lock();
  107. int exitMagicNumber = args->m_cs->getSharedParam(1);
  108. requestExit = (exitMagicNumber==MAGIC_RESET_NUMBER);
  109. args->m_cs->unlock();
  110. }
  111. printf("finished\n");
  112. //do nothing
  113. }
  114. void* SamplelsMemoryFunc()
  115. {
  116. //don't create local store memory, just return 0
  117. return new SampleThreadLocalStorage;
  118. }
  119. class MultiThreadingExample : public CommonExampleInterface
  120. {
  121. CommonGraphicsApp* m_app;
  122. GUIHelperInterface* m_guiHelper;
  123. int m_exampleIndex;
  124. b3ThreadSupportInterface* m_threadSupport;
  125. btAlignedObjectArray<SampleJob1*> m_jobs;
  126. int m_numThreads;
  127. public:
  128. MultiThreadingExample(GUIHelperInterface* guiHelper, int tutorialIndex)
  129. :m_app(guiHelper->getAppInterface()),
  130. m_guiHelper(guiHelper),
  131. m_exampleIndex(tutorialIndex),
  132. m_threadSupport(0),
  133. m_numThreads(8)
  134. {
  135. int numBodies = 1;
  136. m_app->setUpAxis(1);
  137. m_app->m_renderer->enableBlend(true);
  138. }
  139. virtual ~MultiThreadingExample()
  140. {
  141. m_app->m_renderer->enableBlend(false);
  142. }
  143. virtual void renderScene()
  144. {
  145. }
  146. virtual void initPhysics()
  147. {
  148. b3Printf("initPhysics");
  149. m_threadSupport = createThreadSupport(m_numThreads);
  150. for (int i=0;i<m_threadSupport->getNumTasks();i++)
  151. {
  152. SampleThreadLocalStorage* storage = (SampleThreadLocalStorage*)m_threadSupport->getThreadLocalMemory(i);
  153. b3Assert(storage);
  154. storage->threadId = i;
  155. }
  156. args.m_cs = m_threadSupport->createCriticalSection();
  157. args.m_cs->setSharedParam(0,100);
  158. for (int i=0;i<100;i++)
  159. {
  160. SampleJob1* job = new SampleJob1(i);
  161. args.submitJob(job);
  162. }
  163. int i;
  164. for (i=0;i<m_numThreads;i++)
  165. {
  166. m_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*) &args, i);
  167. }
  168. b3Printf("Threads started");
  169. }
  170. virtual void exitPhysics()
  171. {
  172. b3Printf("exitPhysics, stopping threads");
  173. bool blockingWait =false;
  174. int arg0,arg1;
  175. args.m_cs->lock();
  176. //terminate all threads
  177. args.m_cs->setSharedParam(1,MAGIC_RESET_NUMBER);
  178. args.m_cs->unlock();
  179. if (blockingWait)
  180. {
  181. for (int i=0;i<m_numThreads;i++)
  182. {
  183. m_threadSupport->waitForResponse(&arg0,&arg1);
  184. printf("finished waiting for response: %d %d\n", arg0,arg1);
  185. }
  186. } else
  187. {
  188. int numActiveThreads = m_numThreads;
  189. while (numActiveThreads)
  190. {
  191. if (m_threadSupport->isTaskCompleted(&arg0,&arg1,0))
  192. {
  193. numActiveThreads--;
  194. printf("numActiveThreads = %d\n",numActiveThreads);
  195. } else
  196. {
  197. // printf("polling..");
  198. }
  199. };
  200. }
  201. delete m_threadSupport;
  202. b3Printf("Threads stopped");
  203. for (int i=0;i<m_jobs.size();i++)
  204. {
  205. delete m_jobs[i];
  206. }
  207. m_jobs.clear();
  208. }
  209. virtual void stepSimulation(float deltaTime)
  210. {
  211. }
  212. virtual void physicsDebugDraw(int debugDrawFlags)
  213. {
  214. }
  215. virtual bool mouseMoveCallback(float x,float y)
  216. {
  217. return false;
  218. }
  219. virtual bool mouseButtonCallback(int button, int state, float x, float y)
  220. {
  221. return false;
  222. }
  223. virtual bool keyboardCallback(int key, int state)
  224. {
  225. return false;
  226. }
  227. virtual void resetCamera()
  228. {
  229. float dist = 10.5;
  230. float pitch = 136;
  231. float yaw = 32;
  232. float targetPos[3]={0,0,0};
  233. if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
  234. {
  235. m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
  236. m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
  237. m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
  238. m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]);
  239. }
  240. }
  241. };
  242. class CommonExampleInterface* MultiThreadingExampleCreateFunc(struct CommonExampleOptions& options)
  243. {
  244. return new MultiThreadingExample(options.m_guiHelper, options.m_option);
  245. }