Bullet Collision Detection & Physics Library
MiniCLTaskScheduler.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
16 //#define __CELLOS_LV2__ 1
17 #define __BT_SKIP_UINT64_H 1
18 
19 #define USE_SAMPLE_PROCESS 1
20 #ifdef USE_SAMPLE_PROCESS
21 
22 
23 #include "MiniCLTaskScheduler.h"
24 #include <stdio.h>
25 
26 #ifdef __SPU__
27 
28 
29 
30 void SampleThreadFunc(void* userPtr,void* lsMemory)
31 {
32  //do nothing
33  printf("hello world\n");
34 }
35 
36 
37 void* SamplelsMemoryFunc()
38 {
39  //don't create local store memory, just return 0
40  return 0;
41 }
42 
43 
44 #else
45 
46 
48 
49 //# include "SPUAssert.h"
50 #include <string.h>
51 
52 #include "MiniCL/cl_platform.h"
53 
54 extern "C" {
55  extern char SPU_SAMPLE_ELF_SYMBOL[];
56 }
57 
58 
59 MiniCLTaskScheduler::MiniCLTaskScheduler(btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks)
60 :m_threadInterface(threadInterface),
61 m_maxNumOutstandingTasks(maxNumOutstandingTasks)
62 {
63 
66 
67  m_kernels.resize(0);
68 
69  for (int i = 0; i < m_maxNumOutstandingTasks; i++)
70  {
71  m_taskBusy[i] = false;
72  }
73  m_numBusyTasks = 0;
74  m_currentTask = 0;
75 
76  m_initialized = false;
77 
79 
80 
81 }
82 
84 {
86 
87 }
88 
89 
90 
92 {
93 #ifdef DEBUG_SPU_TASK_SCHEDULING
94  printf("MiniCLTaskScheduler::initialize()\n");
95 #endif //DEBUG_SPU_TASK_SCHEDULING
96 
97  for (int i = 0; i < m_maxNumOutstandingTasks; i++)
98  {
99  m_taskBusy[i] = false;
100  }
101  m_numBusyTasks = 0;
102  m_currentTask = 0;
103  m_initialized = true;
104 
105 }
106 
107 
108 void MiniCLTaskScheduler::issueTask(int firstWorkUnit, int lastWorkUnit, MiniCLKernel* kernel)
109 {
110 
111 #ifdef DEBUG_SPU_TASK_SCHEDULING
112  printf("MiniCLTaskScheduler::issueTask (m_currentTask= %d\)n", m_currentTask);
113 #endif //DEBUG_SPU_TASK_SCHEDULING
114 
115  m_taskBusy[m_currentTask] = true;
116  m_numBusyTasks++;
117 
119  {
120  // send task description in event message
121  taskDesc.m_firstWorkUnit = firstWorkUnit;
122  taskDesc.m_lastWorkUnit = lastWorkUnit;
123  taskDesc.m_kernel = kernel;
124  //some bookkeeping to recognize finished tasks
125  taskDesc.m_taskId = m_currentTask;
126 
127 // for (int i=0;i<MINI_CL_MAX_ARG;i++)
128  for (unsigned int i=0; i < kernel->m_numArgs; i++)
129  {
130  taskDesc.m_argSizes[i] = kernel->m_argSizes[i];
131  if (taskDesc.m_argSizes[i])
132  {
133  taskDesc.m_argData[i] = kernel->m_argData[i];
134 // memcpy(&taskDesc.m_argData[i],&argData[MINICL_MAX_ARGLENGTH*i],taskDesc.m_argSizes[i]);
135  }
136  }
137  }
138 
139 
141 
142  // if all tasks busy, wait for spu event to clear the task.
143 
145  {
146  unsigned int taskId;
147  unsigned int outputSize;
148 
149  for (int i=0;i<m_maxNumOutstandingTasks;i++)
150  {
151  if (m_taskBusy[i])
152  {
153  taskId = i;
154  break;
155  }
156  }
157  m_threadInterface->waitForResponse(&taskId, &outputSize);
158 
159  //printf("PPU: after issue, received event: %u %d\n", taskId, outputSize);
160 
161  postProcess(taskId, outputSize);
162 
163  m_taskBusy[taskId] = false;
164 
165  m_numBusyTasks--;
166  }
167 
168  // find new task buffer
169  for (int i = 0; i < m_maxNumOutstandingTasks; i++)
170  {
171  if (!m_taskBusy[i])
172  {
173  m_currentTask = i;
174  break;
175  }
176  }
177 }
178 
179 
181 void MiniCLTaskScheduler::postProcess(int taskId, int outputSize)
182 {
183 
184 }
185 
186 
188 {
189 #ifdef DEBUG_SPU_TASK_SCHEDULING
190  printf("\nSpuCollisionTaskProcess::flush()\n");
191 #endif //DEBUG_SPU_TASK_SCHEDULING
192 
193 
194  // all tasks are issued, wait for all tasks to be complete
195  while(m_numBusyTasks > 0)
196  {
197 // Consolidating SPU code
198  unsigned int taskId;
199  unsigned int outputSize;
200 
201  for (int i=0;i<m_maxNumOutstandingTasks;i++)
202  {
203  if (m_taskBusy[i])
204  {
205  taskId = i;
206  break;
207  }
208  }
209  {
210 
211  m_threadInterface->waitForResponse(&taskId, &outputSize);
212  }
213 
214  //printf("PPU: flushing, received event: %u %d\n", taskId, outputSize);
215 
216  postProcess(taskId, outputSize);
217 
218  m_taskBusy[taskId] = false;
219 
220  m_numBusyTasks--;
221  }
222 
223 
224 }
225 
226 
227 
228 typedef void (*MiniCLKernelLauncher0)(int);
229 typedef void (*MiniCLKernelLauncher1)(void*, int);
230 typedef void (*MiniCLKernelLauncher2)(void*, void*, int);
231 typedef void (*MiniCLKernelLauncher3)(void*, void*, void*, int);
232 typedef void (*MiniCLKernelLauncher4)(void*, void*, void*, void*, int);
233 typedef void (*MiniCLKernelLauncher5)(void*, void*, void*, void*, void*, int);
234 typedef void (*MiniCLKernelLauncher6)(void*, void*, void*, void*, void*, void*, int);
235 typedef void (*MiniCLKernelLauncher7)(void*, void*, void*, void*, void*, void*, void*, int);
236 typedef void (*MiniCLKernelLauncher8)(void*, void*, void*, void*, void*, void*, void*, void*, int);
237 typedef void (*MiniCLKernelLauncher9)(void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
238 typedef void (*MiniCLKernelLauncher10)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
239 typedef void (*MiniCLKernelLauncher11)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
240 typedef void (*MiniCLKernelLauncher12)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
241 typedef void (*MiniCLKernelLauncher13)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
242 typedef void (*MiniCLKernelLauncher14)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
243 typedef void (*MiniCLKernelLauncher15)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
244 typedef void (*MiniCLKernelLauncher16)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
245 
246 
247 static void kernelLauncher0(MiniCLTaskDesc* taskDesc, int guid)
248 {
249  ((MiniCLKernelLauncher0)(taskDesc->m_kernel->m_launcher))(guid);
250 }
251 static void kernelLauncher1(MiniCLTaskDesc* taskDesc, int guid)
252 {
253  ((MiniCLKernelLauncher1)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0],
254  guid);
255 }
256 static void kernelLauncher2(MiniCLTaskDesc* taskDesc, int guid)
257 {
258  ((MiniCLKernelLauncher2)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0],
259  taskDesc->m_argData[1],
260  guid);
261 }
262 static void kernelLauncher3(MiniCLTaskDesc* taskDesc, int guid)
263 {
264  ((MiniCLKernelLauncher3)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0],
265  taskDesc->m_argData[1],
266  taskDesc->m_argData[2],
267  guid);
268 }
269 static void kernelLauncher4(MiniCLTaskDesc* taskDesc, int guid)
270 {
271  ((MiniCLKernelLauncher4)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0],
272  taskDesc->m_argData[1],
273  taskDesc->m_argData[2],
274  taskDesc->m_argData[3],
275  guid);
276 }
277 static void kernelLauncher5(MiniCLTaskDesc* taskDesc, int guid)
278 {
279  ((MiniCLKernelLauncher5)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0],
280  taskDesc->m_argData[1],
281  taskDesc->m_argData[2],
282  taskDesc->m_argData[3],
283  taskDesc->m_argData[4],
284  guid);
285 }
286 static void kernelLauncher6(MiniCLTaskDesc* taskDesc, int guid)
287 {
288  ((MiniCLKernelLauncher6)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0],
289  taskDesc->m_argData[1],
290  taskDesc->m_argData[2],
291  taskDesc->m_argData[3],
292  taskDesc->m_argData[4],
293  taskDesc->m_argData[5],
294  guid);
295 }
296 static void kernelLauncher7(MiniCLTaskDesc* taskDesc, int guid)
297 {
298  ((MiniCLKernelLauncher7)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0],
299  taskDesc->m_argData[1],
300  taskDesc->m_argData[2],
301  taskDesc->m_argData[3],
302  taskDesc->m_argData[4],
303  taskDesc->m_argData[5],
304  taskDesc->m_argData[6],
305  guid);
306 }
307 static void kernelLauncher8(MiniCLTaskDesc* taskDesc, int guid)
308 {
309  ((MiniCLKernelLauncher8)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0],
310  taskDesc->m_argData[1],
311  taskDesc->m_argData[2],
312  taskDesc->m_argData[3],
313  taskDesc->m_argData[4],
314  taskDesc->m_argData[5],
315  taskDesc->m_argData[6],
316  taskDesc->m_argData[7],
317  guid);
318 }
319 static void kernelLauncher9(MiniCLTaskDesc* taskDesc, int guid)
320 {
321  ((MiniCLKernelLauncher9)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0],
322  taskDesc->m_argData[1],
323  taskDesc->m_argData[2],
324  taskDesc->m_argData[3],
325  taskDesc->m_argData[4],
326  taskDesc->m_argData[5],
327  taskDesc->m_argData[6],
328  taskDesc->m_argData[7],
329  taskDesc->m_argData[8],
330  guid);
331 }
332 static void kernelLauncher10(MiniCLTaskDesc* taskDesc, int guid)
333 {
334  ((MiniCLKernelLauncher10)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0],
335  taskDesc->m_argData[1],
336  taskDesc->m_argData[2],
337  taskDesc->m_argData[3],
338  taskDesc->m_argData[4],
339  taskDesc->m_argData[5],
340  taskDesc->m_argData[6],
341  taskDesc->m_argData[7],
342  taskDesc->m_argData[8],
343  taskDesc->m_argData[9],
344  guid);
345 }
346 static void kernelLauncher11(MiniCLTaskDesc* taskDesc, int guid)
347 {
348  ((MiniCLKernelLauncher11)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0],
349  taskDesc->m_argData[1],
350  taskDesc->m_argData[2],
351  taskDesc->m_argData[3],
352  taskDesc->m_argData[4],
353  taskDesc->m_argData[5],
354  taskDesc->m_argData[6],
355  taskDesc->m_argData[7],
356  taskDesc->m_argData[8],
357  taskDesc->m_argData[9],
358  taskDesc->m_argData[10],
359  guid);
360 }
361 static void kernelLauncher12(MiniCLTaskDesc* taskDesc, int guid)
362 {
363  ((MiniCLKernelLauncher12)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0],
364  taskDesc->m_argData[1],
365  taskDesc->m_argData[2],
366  taskDesc->m_argData[3],
367  taskDesc->m_argData[4],
368  taskDesc->m_argData[5],
369  taskDesc->m_argData[6],
370  taskDesc->m_argData[7],
371  taskDesc->m_argData[8],
372  taskDesc->m_argData[9],
373  taskDesc->m_argData[10],
374  taskDesc->m_argData[11],
375  guid);
376 }
377 static void kernelLauncher13(MiniCLTaskDesc* taskDesc, int guid)
378 {
379  ((MiniCLKernelLauncher13)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0],
380  taskDesc->m_argData[1],
381  taskDesc->m_argData[2],
382  taskDesc->m_argData[3],
383  taskDesc->m_argData[4],
384  taskDesc->m_argData[5],
385  taskDesc->m_argData[6],
386  taskDesc->m_argData[7],
387  taskDesc->m_argData[8],
388  taskDesc->m_argData[9],
389  taskDesc->m_argData[10],
390  taskDesc->m_argData[11],
391  taskDesc->m_argData[12],
392  guid);
393 }
394 static void kernelLauncher14(MiniCLTaskDesc* taskDesc, int guid)
395 {
396  ((MiniCLKernelLauncher14)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0],
397  taskDesc->m_argData[1],
398  taskDesc->m_argData[2],
399  taskDesc->m_argData[3],
400  taskDesc->m_argData[4],
401  taskDesc->m_argData[5],
402  taskDesc->m_argData[6],
403  taskDesc->m_argData[7],
404  taskDesc->m_argData[8],
405  taskDesc->m_argData[9],
406  taskDesc->m_argData[10],
407  taskDesc->m_argData[11],
408  taskDesc->m_argData[12],
409  taskDesc->m_argData[13],
410  guid);
411 }
412 static void kernelLauncher15(MiniCLTaskDesc* taskDesc, int guid)
413 {
414  ((MiniCLKernelLauncher15)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0],
415  taskDesc->m_argData[1],
416  taskDesc->m_argData[2],
417  taskDesc->m_argData[3],
418  taskDesc->m_argData[4],
419  taskDesc->m_argData[5],
420  taskDesc->m_argData[6],
421  taskDesc->m_argData[7],
422  taskDesc->m_argData[8],
423  taskDesc->m_argData[9],
424  taskDesc->m_argData[10],
425  taskDesc->m_argData[11],
426  taskDesc->m_argData[12],
427  taskDesc->m_argData[13],
428  taskDesc->m_argData[14],
429  guid);
430 }
431 static void kernelLauncher16(MiniCLTaskDesc* taskDesc, int guid)
432 {
433  ((MiniCLKernelLauncher16)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0],
434  taskDesc->m_argData[1],
435  taskDesc->m_argData[2],
436  taskDesc->m_argData[3],
437  taskDesc->m_argData[4],
438  taskDesc->m_argData[5],
439  taskDesc->m_argData[6],
440  taskDesc->m_argData[7],
441  taskDesc->m_argData[8],
442  taskDesc->m_argData[9],
443  taskDesc->m_argData[10],
444  taskDesc->m_argData[11],
445  taskDesc->m_argData[12],
446  taskDesc->m_argData[13],
447  taskDesc->m_argData[14],
448  taskDesc->m_argData[15],
449  guid);
450 }
451 
453 {
471 };
472 
474 {
476 }
477 
479 {
480  void* pCode;
481  const char* pName;
482 };
484 static int sNumKernelDesc = 0;
485 
486 MiniCLKernelDesc::MiniCLKernelDesc(void* pCode, const char* pName)
487 {
488  for(int i = 0; i < sNumKernelDesc; i++)
489  {
490  if(!strcmp(pName, spKernelDesc[i].pName))
491  { // already registered
492  btAssert(spKernelDesc[i].pCode == pCode);
493  return;
494  }
495  }
496  spKernelDesc[sNumKernelDesc].pCode = pCode;
497  spKernelDesc[sNumKernelDesc].pName = pName;
498  sNumKernelDesc++;
499 }
500 
501 
503 {
505  for(int i = 0; i < sNumKernelDesc; i++)
506  {
507  if(!strcmp(m_name, spKernelDesc[i].pName))
508  {
509  m_pCode = spKernelDesc[i].pCode;
510  return this;
511  }
512  }
513  return NULL;
514 }
515 
516 #endif
517 
518 
519 #endif //USE_SAMPLE_PROCESS
int m_argSizes[MINI_CL_MAX_ARG]
char m_name[MINI_CL_MAX_KERNEL_NAME]
static void kernelLauncher12(MiniCLTaskDesc *taskDesc, int guid)
MiniCLKernel * m_kernel
Definition: MiniCLTask.h:48
static void kernelLauncher8(MiniCLTaskDesc *taskDesc, int guid)
static void kernelLauncher3(MiniCLTaskDesc *taskDesc, int guid)
static void kernelLauncher1(MiniCLTaskDesc *taskDesc, int guid)
void(* MiniCLKernelLauncher15)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, int)
void(* MiniCLKernelLauncher13)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, int)
void(* MiniCLKernelLauncher4)(void *, void *, void *, void *, int)
class btThreadSupportInterface * m_threadInterface
virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1)=0
send messages to SPUs
void(* MiniCLKernelLauncher7)(void *, void *, void *, void *, void *, void *, void *, int)
uint32_t ppu_address_t
static int sNumKernelDesc
static kernelLauncherCB spLauncherList[MINI_CL_MAX_ARG+1]
#define btAssert(x)
Definition: btScalar.h:101
void(* MiniCLKernelLauncher14)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, int)
void(* MiniCLKernelLauncher16)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, int)
int m_argSizes[MINI_CL_MAX_ARG]
Definition: MiniCLTask.h:51
void(* MiniCLKernelLauncher0)(int)
static void kernelLauncher6(MiniCLTaskDesc *taskDesc, int guid)
static void kernelLauncher10(MiniCLTaskDesc *taskDesc, int guid)
virtual void startSPU()=0
non-blocking test if a task is completed.
static void kernelLauncher14(MiniCLTaskDesc *taskDesc, int guid)
void(* MiniCLKernelLauncher6)(void *, void *, void *, void *, void *, void *, int)
void(* MiniCLKernelLauncher5)(void *, void *, void *, void *, void *, int)
static void kernelLauncher16(MiniCLTaskDesc *taskDesc, int guid)
btAlignedObjectArray< bool > m_taskBusy
static void kernelLauncher9(MiniCLTaskDesc *taskDesc, int guid)
void * m_argData[MINI_CL_MAX_ARG]
Definition: MiniCLTask.h:50
unsigned int m_numArgs
void registerKernel(MiniCLKernel *kernel)
void postProcess(int taskId, int outputSize)
Optional PPU-size post processing for each task.
static void kernelLauncher0(MiniCLTaskDesc *taskDesc, int guid)
void(* MiniCLKernelLauncher12)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, int)
void(* MiniCLKernelLauncher2)(void *, void *, int)
void(* MiniCLKernelLauncher10)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, int)
void(* MiniCLKernelLauncher9)(void *, void *, void *, void *, void *, void *, void *, void *, void *, int)
static void kernelLauncher13(MiniCLTaskDesc *taskDesc, int guid)
virtual void stopSPU()=0
tell the task scheduler we are done with the SPU tasks
static void kernelLauncher2(MiniCLTaskDesc *taskDesc, int guid)
void issueTask(int firstWorkUnit, int lastWorkUnit, MiniCLKernel *kernel)
void(* MiniCLKernelLauncher3)(void *, void *, void *, int)
void(* MiniCLKernelLauncher1)(void *, int)
static void kernelLauncher7(MiniCLTaskDesc *taskDesc, int guid)
static MiniCLKernelDescEntry spKernelDesc[256]
void resize(int newsize, const T &fillData=T())
btAlignedObjectArray< MiniCLTaskDesc > m_spuSampleTaskDesc
static void kernelLauncher11(MiniCLTaskDesc *taskDesc, int guid)
MiniCLTaskScheduler * m_scheduler
void flush()
call flush to submit potential outstanding work to SPUs and wait for all involved SPUs to be finished...
static void kernelLauncher15(MiniCLTaskDesc *taskDesc, int guid)
char SPU_SAMPLE_ELF_SYMBOL[]
void(* MiniCLKernelLauncher8)(void *, void *, void *, void *, void *, void *, void *, void *, int)
MiniCLKernelDesc(void *pCode, const char *pName)
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1)=0
check for messages from SPUs
uint32_t m_firstWorkUnit
Definition: MiniCLTask.h:45
void(* kernelLauncherCB)(MiniCLTaskDesc *taskDesc, int guid)
void * m_argData[MINI_CL_MAX_ARG]
static void kernelLauncher5(MiniCLTaskDesc *taskDesc, int guid)
uint32_t m_taskId
Definition: MiniCLTask.h:43
uint32_t m_lastWorkUnit
Definition: MiniCLTask.h:46
static void kernelLauncher4(MiniCLTaskDesc *taskDesc, int guid)
void initialize()
call initialize in the beginning of the frame, before addCollisionPairToTask
MiniCLKernel * registerSelf()
void(* MiniCLKernelLauncher11)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, int)
btAlignedObjectArray< const MiniCLKernel * > m_kernels
#define MINI_CL_MAX_ARG
Definition: MiniCLTask.h:26
MiniCLTaskScheduler(btThreadSupportInterface *threadInterface, int maxNumOutstandingTasks)
kernelLauncherCB m_launcher