Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / MiniCL / MiniCLTaskScheduler.h
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
17
18 #ifndef MINICL_TASK_SCHEDULER_H
19 #define MINICL_TASK_SCHEDULER_H
20
21 #include <assert.h>
22
23
24 #include "BulletMultiThreaded/PlatformDefinitions.h"
25
26 #include <stdlib.h>
27
28 #include "LinearMath/btAlignedObjectArray.h"
29
30
31 #include "MiniCLTask/MiniCLTask.h"
32
33 //just add your commands here, try to keep them globally unique for debugging purposes
34 #define CMD_SAMPLE_TASK_COMMAND 10
35
36 struct MiniCLKernel;
37
38 /// MiniCLTaskScheduler handles SPU processing of collision pairs.
39 /// When PPU issues a task, it will look for completed task buffers
40 /// PPU will do postprocessing, dependent on workunit output (not likely)
41 class MiniCLTaskScheduler
42 {
43         // track task buffers that are being used, and total busy tasks
44         btAlignedObjectArray<bool>      m_taskBusy;
45         btAlignedObjectArray<MiniCLTaskDesc>    m_spuSampleTaskDesc;
46
47
48         btAlignedObjectArray<const MiniCLKernel*>       m_kernels;
49
50
51         int   m_numBusyTasks;
52
53         // the current task and the current entry to insert a new work unit
54         int   m_currentTask;
55
56         bool m_initialized;
57
58         void postProcess(int taskId, int outputSize);
59         
60         class   btThreadSupportInterface*       m_threadInterface;
61
62         int     m_maxNumOutstandingTasks;
63
64
65
66 public:
67         MiniCLTaskScheduler(btThreadSupportInterface*   threadInterface, int maxNumOutstandingTasks);
68         
69         ~MiniCLTaskScheduler();
70         
71         ///call initialize in the beginning of the frame, before addCollisionPairToTask
72         void initialize();
73
74         void issueTask(int firstWorkUnit, int lastWorkUnit, MiniCLKernel* kernel);
75
76         ///call flush to submit potential outstanding work to SPUs and wait for all involved SPUs to be finished
77         void flush();
78
79         class   btThreadSupportInterface*       getThreadSupportInterface()
80         {
81                 return m_threadInterface;
82         }
83
84         int     findProgramCommandIdByName(const char* programName) const;
85
86         int getMaxNumOutstandingTasks() const
87         {
88                 return m_maxNumOutstandingTasks;
89         }
90
91         void registerKernel(MiniCLKernel* kernel)
92         {
93                 m_kernels.push_back(kernel);
94         }
95 };
96
97 typedef void (*kernelLauncherCB)(MiniCLTaskDesc* taskDesc, int guid);
98
99 struct  MiniCLKernel
100 {
101         MiniCLTaskScheduler* m_scheduler;
102         
103 //      int     m_kernelProgramCommandId;
104
105         char    m_name[MINI_CL_MAX_KERNEL_NAME];
106         unsigned int    m_numArgs;
107         kernelLauncherCB        m_launcher;
108         void* m_pCode;
109         void updateLauncher();
110         MiniCLKernel* registerSelf();
111
112         void*   m_argData[MINI_CL_MAX_ARG];
113         int                             m_argSizes[MINI_CL_MAX_ARG];
114 };
115
116
117 #if defined(USE_LIBSPE2) && defined(__SPU__)
118 ////////////////////MAIN/////////////////////////////
119 #include "../SpuLibspe2Support.h"
120 #include <spu_intrinsics.h>
121 #include <spu_mfcio.h>
122 #include <SpuFakeDma.h>
123
124 void * SamplelsMemoryFunc();
125 void SampleThreadFunc(void* userPtr,void* lsMemory);
126
127 //#define DEBUG_LIBSPE2_MAINLOOP
128
129 int main(unsigned long long speid, addr64 argp, addr64 envp)
130 {
131         printf("SPU is up \n");
132         
133         ATTRIBUTE_ALIGNED128(btSpuStatus status);
134         ATTRIBUTE_ALIGNED16( SpuSampleTaskDesc taskDesc ) ;
135         unsigned int received_message = Spu_Mailbox_Event_Nothing;
136         bool shutdown = false;
137
138         cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
139         cellDmaWaitTagStatusAll(DMA_MASK(3));
140
141         status.m_status = Spu_Status_Free;
142         status.m_lsMemory.p = SamplelsMemoryFunc();
143
144         cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
145         cellDmaWaitTagStatusAll(DMA_MASK(3));
146         
147         
148         while (!shutdown)
149         {
150                 received_message = spu_read_in_mbox();
151                 
152
153                 
154                 switch(received_message)
155                 {
156                 case Spu_Mailbox_Event_Shutdown:
157                         shutdown = true;
158                         break; 
159                 case Spu_Mailbox_Event_Task:
160                         // refresh the status
161 #ifdef DEBUG_LIBSPE2_MAINLOOP
162                         printf("SPU recieved Task \n");
163 #endif //DEBUG_LIBSPE2_MAINLOOP
164                         cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
165                         cellDmaWaitTagStatusAll(DMA_MASK(3));
166                 
167                         btAssert(status.m_status==Spu_Status_Occupied);
168                         
169                         cellDmaGet(&taskDesc, status.m_taskDesc.p, sizeof(SpuSampleTaskDesc), DMA_TAG(3), 0, 0);
170                         cellDmaWaitTagStatusAll(DMA_MASK(3));
171                         
172                         SampleThreadFunc((void*)&taskDesc, reinterpret_cast<void*> (taskDesc.m_mainMemoryPtr) );
173                         break;
174                 case Spu_Mailbox_Event_Nothing:
175                 default:
176                         break;
177                 }
178
179                 // set to status free and wait for next task
180                 status.m_status = Spu_Status_Free;
181                 cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
182                 cellDmaWaitTagStatusAll(DMA_MASK(3));           
183                                 
184                 
185         }
186         return 0;
187 }
188 //////////////////////////////////////////////////////
189 #endif
190
191
192
193 #endif // MINICL_TASK_SCHEDULER_H
194