Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / BulletMultiThreaded / SpuSampleTaskProcess.cpp
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
46 #include "btThreadSupportInterface.h"
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
66         m_taskBusy.resize(m_maxNumOutstandingTasks);
67         m_spuSampleTaskDesc.resize(m_maxNumOutstandingTasks);
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
78         m_threadInterface->startSPU();
79
80
81 }
82
83 SpuSampleTaskProcess::~SpuSampleTaskProcess()
84 {
85         m_threadInterface->stopSPU();
86         
87 }
88
89
90
91 void    SpuSampleTaskProcess::initialize()
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
118         SpuSampleTaskDesc& taskDesc = m_spuSampleTaskDesc[m_currentTask];
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
133         m_threadInterface->sendRequest(1, (ppu_address_t) &taskDesc, m_currentTask);
134
135         // if all tasks busy, wait for spu event to clear the task.
136         
137         if (m_numBusyTasks >= m_maxNumOutstandingTasks)
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
173 ///Optional PPU-size post processing for each task
174 void SpuSampleTaskProcess::postProcess(int taskId, int outputSize)
175 {
176
177 }
178
179
180 void SpuSampleTaskProcess::flush()
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