Bullet Collision Detection & Physics Library
SpuSampleTaskProcess.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 
18 #define USE_SAMPLE_PROCESS 1
19 #ifdef USE_SAMPLE_PROCESS
20 
21 
22 #include "SpuSampleTaskProcess.h"
23 #include <stdio.h>
24 
25 #ifdef __SPU__
26 
27 
28 
29 void SampleThreadFunc(void* userPtr,void* lsMemory)
30 {
31  //do nothing
32  printf("hello world\n");
33 }
34 
35 
36 void* SamplelsMemoryFunc()
37 {
38  //don't create local store memory, just return 0
39  return 0;
40 }
41 
42 
43 #else
44 
45 
47 
48 //# include "SPUAssert.h"
49 #include <string.h>
50 
51 
52 
53 extern "C" {
54  extern char SPU_SAMPLE_ELF_SYMBOL[];
55 }
56 
57 
58 
59 
60 
61 SpuSampleTaskProcess::SpuSampleTaskProcess(btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks)
62 :m_threadInterface(threadInterface),
63 m_maxNumOutstandingTasks(maxNumOutstandingTasks)
64 {
65 
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("SpuSampleTaskProcess::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 SpuSampleTaskProcess::issueTask(void* sampleMainMemPtr,int sampleValue,int sampleCommand)
109 {
110 
111 #ifdef DEBUG_SPU_TASK_SCHEDULING
112  printf("SpuSampleTaskProcess::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  // no error checking here...
122  // but, currently, event queue can be no larger than NUM_WORKUNIT_TASKS.
123 
124  taskDesc.m_mainMemoryPtr = reinterpret_cast<uint64_t>(sampleMainMemPtr);
125  taskDesc.m_sampleValue = sampleValue;
126  taskDesc.m_sampleCommand = sampleCommand;
127 
128  //some bookkeeping to recognize finished tasks
129  taskDesc.m_taskId = m_currentTask;
130  }
131 
132 
134 
135  // if all tasks busy, wait for spu event to clear the task.
136 
138  {
139  unsigned int taskId;
140  unsigned int outputSize;
141 
142  for (int i=0;i<m_maxNumOutstandingTasks;i++)
143  {
144  if (m_taskBusy[i])
145  {
146  taskId = i;
147  break;
148  }
149  }
150  m_threadInterface->waitForResponse(&taskId, &outputSize);
151 
152  //printf("PPU: after issue, received event: %u %d\n", taskId, outputSize);
153 
154  postProcess(taskId, outputSize);
155 
156  m_taskBusy[taskId] = false;
157 
158  m_numBusyTasks--;
159  }
160 
161  // find new task buffer
162  for (int i = 0; i < m_maxNumOutstandingTasks; i++)
163  {
164  if (!m_taskBusy[i])
165  {
166  m_currentTask = i;
167  break;
168  }
169  }
170 }
171 
172 
174 void SpuSampleTaskProcess::postProcess(int taskId, int outputSize)
175 {
176 
177 }
178 
179 
181 {
182 #ifdef DEBUG_SPU_TASK_SCHEDULING
183  printf("\nSpuCollisionTaskProcess::flush()\n");
184 #endif //DEBUG_SPU_TASK_SCHEDULING
185 
186 
187  // all tasks are issued, wait for all tasks to be complete
188  while(m_numBusyTasks > 0)
189  {
190 // Consolidating SPU code
191  unsigned int taskId;
192  unsigned int outputSize;
193 
194  for (int i=0;i<m_maxNumOutstandingTasks;i++)
195  {
196  if (m_taskBusy[i])
197  {
198  taskId = i;
199  break;
200  }
201  }
202  {
203 
204  m_threadInterface->waitForResponse(&taskId, &outputSize);
205  }
206 
207  //printf("PPU: flushing, received event: %u %d\n", taskId, outputSize);
208 
209  postProcess(taskId, outputSize);
210 
211  m_taskBusy[taskId] = false;
212 
213  m_numBusyTasks--;
214  }
215 
216 
217 }
218 
219 #endif
220 
221 
222 #endif //USE_SAMPLE_PROCESS
SpuSampleTaskProcess(btThreadSupportInterface *threadInterface, int maxNumOutstandingTasks)
unsigned long int uint64_t
void postProcess(int taskId, int outputSize)
Optional PPU-size post processing for each task.
virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1)=0
send messages to SPUs
void issueTask(void *sampleMainMemPtr, int sampleValue, int sampleCommand)
uint32_t ppu_address_t
char SPU_SAMPLE_ELF_SYMBOL[]
virtual void startSPU()=0
non-blocking test if a task is completed.
btAlignedObjectArray< bool > m_taskBusy
void initialize()
call initialize in the beginning of the frame, before addCollisionPairToTask
void flush()
call flush to submit potential outstanding work to SPUs and wait for all involved SPUs to be finished...
class btThreadSupportInterface * m_threadInterface
virtual void stopSPU()=0
tell the task scheduler we are done with the SPU tasks
uint64_t m_mainMemoryPtr
Definition: SpuSampleTask.h:42
void resize(int newsize, const T &fillData=T())
btAlignedObjectArray< SpuSampleTaskDesc > m_spuSampleTaskDesc
uint32_t m_sampleCommand
Definition: SpuSampleTask.h:39
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1)=0
check for messages from SPUs