MiniCLTaskScheduler.cpp

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 //#define __CELLOS_LV2__ 1
00017 #define __BT_SKIP_UINT64_H 1
00018 
00019 #define USE_SAMPLE_PROCESS 1
00020 #ifdef USE_SAMPLE_PROCESS
00021 
00022 
00023 #include "MiniCLTaskScheduler.h"
00024 #include <stdio.h>
00025 
00026 #ifdef __SPU__
00027 
00028 
00029 
00030 void    SampleThreadFunc(void* userPtr,void* lsMemory)
00031 {
00032         //do nothing
00033         printf("hello world\n");
00034 }
00035 
00036 
00037 void*   SamplelsMemoryFunc()
00038 {
00039         //don't create local store memory, just return 0
00040         return 0;
00041 }
00042 
00043 
00044 #else
00045 
00046 
00047 #include "BulletMultiThreaded/btThreadSupportInterface.h"
00048 
00049 //#     include "SPUAssert.h"
00050 #include <string.h>
00051 
00052 #include "MiniCL/cl_platform.h"
00053 
00054 extern "C" {
00055         extern char SPU_SAMPLE_ELF_SYMBOL[];
00056 }
00057 
00058 
00059 MiniCLTaskScheduler::MiniCLTaskScheduler(btThreadSupportInterface*      threadInterface,  int maxNumOutstandingTasks)
00060 :m_threadInterface(threadInterface),
00061 m_maxNumOutstandingTasks(maxNumOutstandingTasks)
00062 {
00063 
00064         m_taskBusy.resize(m_maxNumOutstandingTasks);
00065         m_spuSampleTaskDesc.resize(m_maxNumOutstandingTasks);
00066 
00067         m_kernels.resize(0);
00068 
00069         for (int i = 0; i < m_maxNumOutstandingTasks; i++)
00070         {
00071                 m_taskBusy[i] = false;
00072         }
00073         m_numBusyTasks = 0;
00074         m_currentTask = 0;
00075 
00076         m_initialized = false;
00077 
00078         m_threadInterface->startSPU();
00079 
00080 
00081 }
00082 
00083 MiniCLTaskScheduler::~MiniCLTaskScheduler()
00084 {
00085         m_threadInterface->stopSPU();
00086         
00087 }
00088 
00089 
00090 
00091 void    MiniCLTaskScheduler::initialize()
00092 {
00093 #ifdef DEBUG_SPU_TASK_SCHEDULING
00094         printf("MiniCLTaskScheduler::initialize()\n");
00095 #endif //DEBUG_SPU_TASK_SCHEDULING
00096         
00097         for (int i = 0; i < m_maxNumOutstandingTasks; i++)
00098         {
00099                 m_taskBusy[i] = false;
00100         }
00101         m_numBusyTasks = 0;
00102         m_currentTask = 0;
00103         m_initialized = true;
00104 
00105 }
00106 
00107 
00108 void MiniCLTaskScheduler::issueTask(int firstWorkUnit, int lastWorkUnit, MiniCLKernel* kernel)
00109 {
00110 
00111 #ifdef DEBUG_SPU_TASK_SCHEDULING
00112         printf("MiniCLTaskScheduler::issueTask (m_currentTask= %d\)n", m_currentTask);
00113 #endif //DEBUG_SPU_TASK_SCHEDULING
00114 
00115         m_taskBusy[m_currentTask] = true;
00116         m_numBusyTasks++;
00117 
00118         MiniCLTaskDesc& taskDesc = m_spuSampleTaskDesc[m_currentTask];
00119         {
00120                 // send task description in event message
00121                 taskDesc.m_firstWorkUnit = firstWorkUnit;
00122                 taskDesc.m_lastWorkUnit = lastWorkUnit;
00123                 taskDesc.m_kernel = kernel;
00124                 //some bookkeeping to recognize finished tasks
00125                 taskDesc.m_taskId = m_currentTask;
00126                 
00127 //              for (int i=0;i<MINI_CL_MAX_ARG;i++)
00128                 for (unsigned int i=0; i < kernel->m_numArgs; i++)
00129                 {
00130                         taskDesc.m_argSizes[i] = kernel->m_argSizes[i];
00131                         if (taskDesc.m_argSizes[i])
00132                         {
00133                                 taskDesc.m_argData[i] = kernel->m_argData[i];
00134 //                              memcpy(&taskDesc.m_argData[i],&argData[MINICL_MAX_ARGLENGTH*i],taskDesc.m_argSizes[i]);
00135                         }
00136                 }
00137         }
00138 
00139 
00140         m_threadInterface->sendRequest(1, (ppu_address_t) &taskDesc, m_currentTask);
00141 
00142         // if all tasks busy, wait for spu event to clear the task.
00143         
00144         if (m_numBusyTasks >= m_maxNumOutstandingTasks)
00145         {
00146                 unsigned int taskId;
00147                 unsigned int outputSize;
00148 
00149                 for (int i=0;i<m_maxNumOutstandingTasks;i++)
00150           {
00151                   if (m_taskBusy[i])
00152                   {
00153                           taskId = i;
00154                           break;
00155                   }
00156           }
00157                 m_threadInterface->waitForResponse(&taskId, &outputSize);
00158 
00159                 //printf("PPU: after issue, received event: %u %d\n", taskId, outputSize);
00160 
00161                 postProcess(taskId, outputSize);
00162 
00163                 m_taskBusy[taskId] = false;
00164 
00165                 m_numBusyTasks--;
00166         }
00167 
00168         // find new task buffer
00169         for (int i = 0; i < m_maxNumOutstandingTasks; i++)
00170         {
00171                 if (!m_taskBusy[i])
00172                 {
00173                         m_currentTask = i;
00174                         break;
00175                 }
00176         }
00177 }
00178 
00179 
00181 void MiniCLTaskScheduler::postProcess(int taskId, int outputSize)
00182 {
00183 
00184 }
00185 
00186 
00187 void MiniCLTaskScheduler::flush()
00188 {
00189 #ifdef DEBUG_SPU_TASK_SCHEDULING
00190         printf("\nSpuCollisionTaskProcess::flush()\n");
00191 #endif //DEBUG_SPU_TASK_SCHEDULING
00192         
00193 
00194         // all tasks are issued, wait for all tasks to be complete
00195         while(m_numBusyTasks > 0)
00196         {
00197 // Consolidating SPU code
00198           unsigned int taskId;
00199           unsigned int outputSize;
00200           
00201           for (int i=0;i<m_maxNumOutstandingTasks;i++)
00202           {
00203                   if (m_taskBusy[i])
00204                   {
00205                           taskId = i;
00206                           break;
00207                   }
00208           }
00209           {
00210                         
00211                   m_threadInterface->waitForResponse(&taskId, &outputSize);
00212           }
00213 
00214                 //printf("PPU: flushing, received event: %u %d\n", taskId, outputSize);
00215 
00216                 postProcess(taskId, outputSize);
00217 
00218                 m_taskBusy[taskId] = false;
00219 
00220                 m_numBusyTasks--;
00221         }
00222 
00223 
00224 }
00225 
00226 
00227 
00228 typedef void (*MiniCLKernelLauncher0)(int);
00229 typedef void (*MiniCLKernelLauncher1)(void*, int);
00230 typedef void (*MiniCLKernelLauncher2)(void*, void*, int);
00231 typedef void (*MiniCLKernelLauncher3)(void*, void*, void*, int);
00232 typedef void (*MiniCLKernelLauncher4)(void*, void*, void*, void*, int);
00233 typedef void (*MiniCLKernelLauncher5)(void*, void*, void*, void*, void*, int);
00234 typedef void (*MiniCLKernelLauncher6)(void*, void*, void*, void*, void*, void*, int);
00235 typedef void (*MiniCLKernelLauncher7)(void*, void*, void*, void*, void*, void*, void*, int);
00236 typedef void (*MiniCLKernelLauncher8)(void*, void*, void*, void*, void*, void*, void*, void*, int);
00237 typedef void (*MiniCLKernelLauncher9)(void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
00238 typedef void (*MiniCLKernelLauncher10)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
00239 typedef void (*MiniCLKernelLauncher11)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
00240 typedef void (*MiniCLKernelLauncher12)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
00241 typedef void (*MiniCLKernelLauncher13)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
00242 typedef void (*MiniCLKernelLauncher14)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
00243 typedef void (*MiniCLKernelLauncher15)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
00244 typedef void (*MiniCLKernelLauncher16)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, int);
00245 
00246 
00247 static void kernelLauncher0(MiniCLTaskDesc* taskDesc, int guid)
00248 {
00249         ((MiniCLKernelLauncher0)(taskDesc->m_kernel->m_launcher))(guid);
00250 }
00251 static void kernelLauncher1(MiniCLTaskDesc* taskDesc, int guid)
00252 {
00253         ((MiniCLKernelLauncher1)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], 
00254                                                                                                 guid);
00255 }
00256 static void kernelLauncher2(MiniCLTaskDesc* taskDesc, int guid)
00257 {
00258         ((MiniCLKernelLauncher2)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], 
00259                                                                                                 taskDesc->m_argData[1], 
00260                                                                                                 guid);
00261 }
00262 static void kernelLauncher3(MiniCLTaskDesc* taskDesc, int guid)
00263 {
00264         ((MiniCLKernelLauncher3)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], 
00265                                                                                                 taskDesc->m_argData[1], 
00266                                                                                                 taskDesc->m_argData[2], 
00267                                                                                                 guid);
00268 }
00269 static void kernelLauncher4(MiniCLTaskDesc* taskDesc, int guid)
00270 {
00271         ((MiniCLKernelLauncher4)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], 
00272                                                                                                 taskDesc->m_argData[1], 
00273                                                                                                 taskDesc->m_argData[2], 
00274                                                                                                 taskDesc->m_argData[3], 
00275                                                                                                 guid);
00276 }
00277 static void kernelLauncher5(MiniCLTaskDesc* taskDesc, int guid)
00278 {
00279         ((MiniCLKernelLauncher5)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], 
00280                                                                                                 taskDesc->m_argData[1], 
00281                                                                                                 taskDesc->m_argData[2], 
00282                                                                                                 taskDesc->m_argData[3], 
00283                                                                                                 taskDesc->m_argData[4], 
00284                                                                                                 guid);
00285 }
00286 static void kernelLauncher6(MiniCLTaskDesc* taskDesc, int guid)
00287 {
00288         ((MiniCLKernelLauncher6)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], 
00289                                                                                                 taskDesc->m_argData[1], 
00290                                                                                                 taskDesc->m_argData[2], 
00291                                                                                                 taskDesc->m_argData[3], 
00292                                                                                                 taskDesc->m_argData[4], 
00293                                                                                                 taskDesc->m_argData[5], 
00294                                                                                                 guid);
00295 }
00296 static void kernelLauncher7(MiniCLTaskDesc* taskDesc, int guid)
00297 {
00298         ((MiniCLKernelLauncher7)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], 
00299                                                                                                 taskDesc->m_argData[1], 
00300                                                                                                 taskDesc->m_argData[2], 
00301                                                                                                 taskDesc->m_argData[3], 
00302                                                                                                 taskDesc->m_argData[4], 
00303                                                                                                 taskDesc->m_argData[5], 
00304                                                                                                 taskDesc->m_argData[6], 
00305                                                                                                 guid);
00306 }
00307 static void kernelLauncher8(MiniCLTaskDesc* taskDesc, int guid)
00308 {
00309         ((MiniCLKernelLauncher8)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], 
00310                                                                                                 taskDesc->m_argData[1], 
00311                                                                                                 taskDesc->m_argData[2], 
00312                                                                                                 taskDesc->m_argData[3], 
00313                                                                                                 taskDesc->m_argData[4], 
00314                                                                                                 taskDesc->m_argData[5], 
00315                                                                                                 taskDesc->m_argData[6], 
00316                                                                                                 taskDesc->m_argData[7], 
00317                                                                                                 guid);
00318 }
00319 static void kernelLauncher9(MiniCLTaskDesc* taskDesc, int guid)
00320 {
00321         ((MiniCLKernelLauncher9)(taskDesc->m_kernel->m_pCode))( taskDesc->m_argData[0], 
00322                                                                                                 taskDesc->m_argData[1], 
00323                                                                                                 taskDesc->m_argData[2], 
00324                                                                                                 taskDesc->m_argData[3], 
00325                                                                                                 taskDesc->m_argData[4], 
00326                                                                                                 taskDesc->m_argData[5], 
00327                                                                                                 taskDesc->m_argData[6], 
00328                                                                                                 taskDesc->m_argData[7], 
00329                                                                                                 taskDesc->m_argData[8], 
00330                                                                                                 guid);
00331 }
00332 static void kernelLauncher10(MiniCLTaskDesc* taskDesc, int guid)
00333 {
00334         ((MiniCLKernelLauncher10)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], 
00335                                                                                                 taskDesc->m_argData[1], 
00336                                                                                                 taskDesc->m_argData[2], 
00337                                                                                                 taskDesc->m_argData[3], 
00338                                                                                                 taskDesc->m_argData[4], 
00339                                                                                                 taskDesc->m_argData[5], 
00340                                                                                                 taskDesc->m_argData[6], 
00341                                                                                                 taskDesc->m_argData[7], 
00342                                                                                                 taskDesc->m_argData[8], 
00343                                                                                                 taskDesc->m_argData[9], 
00344                                                                                                 guid);
00345 }
00346 static void kernelLauncher11(MiniCLTaskDesc* taskDesc, int guid)
00347 {
00348         ((MiniCLKernelLauncher11)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], 
00349                                                                                                 taskDesc->m_argData[1], 
00350                                                                                                 taskDesc->m_argData[2], 
00351                                                                                                 taskDesc->m_argData[3], 
00352                                                                                                 taskDesc->m_argData[4], 
00353                                                                                                 taskDesc->m_argData[5], 
00354                                                                                                 taskDesc->m_argData[6], 
00355                                                                                                 taskDesc->m_argData[7], 
00356                                                                                                 taskDesc->m_argData[8], 
00357                                                                                                 taskDesc->m_argData[9], 
00358                                                                                                 taskDesc->m_argData[10], 
00359                                                                                                 guid);
00360 }
00361 static void kernelLauncher12(MiniCLTaskDesc* taskDesc, int guid)
00362 {
00363         ((MiniCLKernelLauncher12)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], 
00364                                                                                                 taskDesc->m_argData[1], 
00365                                                                                                 taskDesc->m_argData[2], 
00366                                                                                                 taskDesc->m_argData[3], 
00367                                                                                                 taskDesc->m_argData[4], 
00368                                                                                                 taskDesc->m_argData[5], 
00369                                                                                                 taskDesc->m_argData[6], 
00370                                                                                                 taskDesc->m_argData[7], 
00371                                                                                                 taskDesc->m_argData[8], 
00372                                                                                                 taskDesc->m_argData[9], 
00373                                                                                                 taskDesc->m_argData[10], 
00374                                                                                                 taskDesc->m_argData[11], 
00375                                                                                                 guid);
00376 }
00377 static void kernelLauncher13(MiniCLTaskDesc* taskDesc, int guid)
00378 {
00379         ((MiniCLKernelLauncher13)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], 
00380                                                                                                 taskDesc->m_argData[1], 
00381                                                                                                 taskDesc->m_argData[2], 
00382                                                                                                 taskDesc->m_argData[3], 
00383                                                                                                 taskDesc->m_argData[4], 
00384                                                                                                 taskDesc->m_argData[5], 
00385                                                                                                 taskDesc->m_argData[6], 
00386                                                                                                 taskDesc->m_argData[7], 
00387                                                                                                 taskDesc->m_argData[8], 
00388                                                                                                 taskDesc->m_argData[9], 
00389                                                                                                 taskDesc->m_argData[10], 
00390                                                                                                 taskDesc->m_argData[11], 
00391                                                                                                 taskDesc->m_argData[12], 
00392                                                                                                 guid);
00393 }
00394 static void kernelLauncher14(MiniCLTaskDesc* taskDesc, int guid)
00395 {
00396         ((MiniCLKernelLauncher14)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], 
00397                                                                                                 taskDesc->m_argData[1], 
00398                                                                                                 taskDesc->m_argData[2], 
00399                                                                                                 taskDesc->m_argData[3], 
00400                                                                                                 taskDesc->m_argData[4], 
00401                                                                                                 taskDesc->m_argData[5], 
00402                                                                                                 taskDesc->m_argData[6], 
00403                                                                                                 taskDesc->m_argData[7], 
00404                                                                                                 taskDesc->m_argData[8], 
00405                                                                                                 taskDesc->m_argData[9], 
00406                                                                                                 taskDesc->m_argData[10], 
00407                                                                                                 taskDesc->m_argData[11], 
00408                                                                                                 taskDesc->m_argData[12], 
00409                                                                                                 taskDesc->m_argData[13], 
00410                                                                                                 guid);
00411 }
00412 static void kernelLauncher15(MiniCLTaskDesc* taskDesc, int guid)
00413 {
00414         ((MiniCLKernelLauncher15)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], 
00415                                                                                                 taskDesc->m_argData[1], 
00416                                                                                                 taskDesc->m_argData[2], 
00417                                                                                                 taskDesc->m_argData[3], 
00418                                                                                                 taskDesc->m_argData[4], 
00419                                                                                                 taskDesc->m_argData[5], 
00420                                                                                                 taskDesc->m_argData[6], 
00421                                                                                                 taskDesc->m_argData[7], 
00422                                                                                                 taskDesc->m_argData[8], 
00423                                                                                                 taskDesc->m_argData[9], 
00424                                                                                                 taskDesc->m_argData[10], 
00425                                                                                                 taskDesc->m_argData[11], 
00426                                                                                                 taskDesc->m_argData[12], 
00427                                                                                                 taskDesc->m_argData[13], 
00428                                                                                                 taskDesc->m_argData[14], 
00429                                                                                                 guid);
00430 }
00431 static void kernelLauncher16(MiniCLTaskDesc* taskDesc, int guid)
00432 {
00433         ((MiniCLKernelLauncher16)(taskDesc->m_kernel->m_pCode))(taskDesc->m_argData[0], 
00434                                                                                                 taskDesc->m_argData[1], 
00435                                                                                                 taskDesc->m_argData[2], 
00436                                                                                                 taskDesc->m_argData[3], 
00437                                                                                                 taskDesc->m_argData[4], 
00438                                                                                                 taskDesc->m_argData[5], 
00439                                                                                                 taskDesc->m_argData[6], 
00440                                                                                                 taskDesc->m_argData[7], 
00441                                                                                                 taskDesc->m_argData[8], 
00442                                                                                                 taskDesc->m_argData[9], 
00443                                                                                                 taskDesc->m_argData[10], 
00444                                                                                                 taskDesc->m_argData[11], 
00445                                                                                                 taskDesc->m_argData[12], 
00446                                                                                                 taskDesc->m_argData[13], 
00447                                                                                                 taskDesc->m_argData[14], 
00448                                                                                                 taskDesc->m_argData[15], 
00449                                                                                                 guid);
00450 }
00451 
00452 static kernelLauncherCB spLauncherList[MINI_CL_MAX_ARG+1] = 
00453 {
00454         kernelLauncher0,
00455         kernelLauncher1,
00456         kernelLauncher2,
00457         kernelLauncher3,
00458         kernelLauncher4,
00459         kernelLauncher5,
00460         kernelLauncher6,
00461         kernelLauncher7,
00462         kernelLauncher8,
00463         kernelLauncher9,
00464         kernelLauncher10,
00465         kernelLauncher11,
00466         kernelLauncher12,
00467         kernelLauncher13,
00468         kernelLauncher14,
00469         kernelLauncher15,
00470         kernelLauncher16
00471 };
00472 
00473 void MiniCLKernel::updateLauncher()
00474 {
00475         m_launcher = spLauncherList[m_numArgs];
00476 }
00477 
00478 struct MiniCLKernelDescEntry
00479 {
00480         void* pCode;
00481         const char* pName;
00482 };
00483 static MiniCLKernelDescEntry spKernelDesc[256];
00484 static int sNumKernelDesc = 0;
00485 
00486 MiniCLKernelDesc::MiniCLKernelDesc(void* pCode, const char* pName)
00487 {
00488         for(int i = 0; i < sNumKernelDesc; i++)
00489         {
00490                 if(!strcmp(pName, spKernelDesc[i].pName))
00491                 {       // already registered
00492                         btAssert(spKernelDesc[i].pCode == pCode);
00493                         return; 
00494                 }
00495         }
00496         spKernelDesc[sNumKernelDesc].pCode = pCode;
00497         spKernelDesc[sNumKernelDesc].pName = pName;
00498         sNumKernelDesc++;
00499 }
00500 
00501 
00502 MiniCLKernel* MiniCLKernel::registerSelf()
00503 {
00504         m_scheduler->registerKernel(this);
00505         for(int i = 0; i < sNumKernelDesc; i++)
00506         {
00507                 if(!strcmp(m_name, spKernelDesc[i].pName))
00508                 {
00509                         m_pCode = spKernelDesc[i].pCode;
00510                         return this;
00511                 }
00512         }
00513         return NULL;
00514 }
00515 
00516 #endif
00517 
00518 
00519 #endif //USE_SAMPLE_PROCESS