MiniCLTaskScheduler.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2007 Erwin Coumans  http://bulletphysics.com
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 
00017 
00018 #ifndef MINICL_TASK_SCHEDULER_H
00019 #define MINICL_TASK_SCHEDULER_H
00020 
00021 #include <assert.h>
00022 
00023 
00024 #include "BulletMultiThreaded/PlatformDefinitions.h"
00025 
00026 #include <stdlib.h>
00027 
00028 #include "LinearMath/btAlignedObjectArray.h"
00029 
00030 
00031 #include "MiniCLTask/MiniCLTask.h"
00032 
00033 //just add your commands here, try to keep them globally unique for debugging purposes
00034 #define CMD_SAMPLE_TASK_COMMAND 10
00035 
00036 struct MiniCLKernel;
00037 
00041 class MiniCLTaskScheduler
00042 {
00043         // track task buffers that are being used, and total busy tasks
00044         btAlignedObjectArray<bool>      m_taskBusy;
00045         btAlignedObjectArray<MiniCLTaskDesc>    m_spuSampleTaskDesc;
00046 
00047 
00048         btAlignedObjectArray<const MiniCLKernel*>       m_kernels;
00049 
00050 
00051         int   m_numBusyTasks;
00052 
00053         // the current task and the current entry to insert a new work unit
00054         int   m_currentTask;
00055 
00056         bool m_initialized;
00057 
00058         void postProcess(int taskId, int outputSize);
00059         
00060         class   btThreadSupportInterface*       m_threadInterface;
00061 
00062         int     m_maxNumOutstandingTasks;
00063 
00064 
00065 
00066 public:
00067         MiniCLTaskScheduler(btThreadSupportInterface*   threadInterface, int maxNumOutstandingTasks);
00068         
00069         ~MiniCLTaskScheduler();
00070         
00072         void initialize();
00073 
00074         void issueTask(int firstWorkUnit, int lastWorkUnit, MiniCLKernel* kernel);
00075 
00077         void flush();
00078 
00079         class   btThreadSupportInterface*       getThreadSupportInterface()
00080         {
00081                 return m_threadInterface;
00082         }
00083 
00084         int     findProgramCommandIdByName(const char* programName) const;
00085 
00086         int getMaxNumOutstandingTasks() const
00087         {
00088                 return m_maxNumOutstandingTasks;
00089         }
00090 
00091         void registerKernel(MiniCLKernel* kernel)
00092         {
00093                 m_kernels.push_back(kernel);
00094         }
00095 };
00096 
00097 typedef void (*kernelLauncherCB)(MiniCLTaskDesc* taskDesc, int guid);
00098 
00099 struct  MiniCLKernel
00100 {
00101         MiniCLTaskScheduler* m_scheduler;
00102         
00103 //      int     m_kernelProgramCommandId;
00104 
00105         char    m_name[MINI_CL_MAX_KERNEL_NAME];
00106         unsigned int    m_numArgs;
00107         kernelLauncherCB        m_launcher;
00108         void* m_pCode;
00109         void updateLauncher();
00110         MiniCLKernel* registerSelf();
00111 
00112         void*   m_argData[MINI_CL_MAX_ARG];
00113         int                             m_argSizes[MINI_CL_MAX_ARG];
00114 };
00115 
00116 
00117 #if defined(USE_LIBSPE2) && defined(__SPU__)
00118 
00119 #include "../SpuLibspe2Support.h"
00120 #include <spu_intrinsics.h>
00121 #include <spu_mfcio.h>
00122 #include <SpuFakeDma.h>
00123 
00124 void * SamplelsMemoryFunc();
00125 void SampleThreadFunc(void* userPtr,void* lsMemory);
00126 
00127 //#define DEBUG_LIBSPE2_MAINLOOP
00128 
00129 int main(unsigned long long speid, addr64 argp, addr64 envp)
00130 {
00131         printf("SPU is up \n");
00132         
00133         ATTRIBUTE_ALIGNED128(btSpuStatus status);
00134         ATTRIBUTE_ALIGNED16( SpuSampleTaskDesc taskDesc ) ;
00135         unsigned int received_message = Spu_Mailbox_Event_Nothing;
00136         bool shutdown = false;
00137 
00138         cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
00139         cellDmaWaitTagStatusAll(DMA_MASK(3));
00140 
00141         status.m_status = Spu_Status_Free;
00142         status.m_lsMemory.p = SamplelsMemoryFunc();
00143 
00144         cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
00145         cellDmaWaitTagStatusAll(DMA_MASK(3));
00146         
00147         
00148         while (!shutdown)
00149         {
00150                 received_message = spu_read_in_mbox();
00151                 
00152 
00153                 
00154                 switch(received_message)
00155                 {
00156                 case Spu_Mailbox_Event_Shutdown:
00157                         shutdown = true;
00158                         break; 
00159                 case Spu_Mailbox_Event_Task:
00160                         // refresh the status
00161 #ifdef DEBUG_LIBSPE2_MAINLOOP
00162                         printf("SPU recieved Task \n");
00163 #endif //DEBUG_LIBSPE2_MAINLOOP
00164                         cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
00165                         cellDmaWaitTagStatusAll(DMA_MASK(3));
00166                 
00167                         btAssert(status.m_status==Spu_Status_Occupied);
00168                         
00169                         cellDmaGet(&taskDesc, status.m_taskDesc.p, sizeof(SpuSampleTaskDesc), DMA_TAG(3), 0, 0);
00170                         cellDmaWaitTagStatusAll(DMA_MASK(3));
00171                         
00172                         SampleThreadFunc((void*)&taskDesc, reinterpret_cast<void*> (taskDesc.m_mainMemoryPtr) );
00173                         break;
00174                 case Spu_Mailbox_Event_Nothing:
00175                 default:
00176                         break;
00177                 }
00178 
00179                 // set to status free and wait for next task
00180                 status.m_status = Spu_Status_Free;
00181                 cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
00182                 cellDmaWaitTagStatusAll(DMA_MASK(3));           
00183                                 
00184                 
00185         }
00186         return 0;
00187 }
00189 #endif
00190 
00191 
00192 
00193 #endif // MINICL_TASK_SCHEDULER_H
00194