SpuSampleTaskProcess.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 
00018 #define USE_SAMPLE_PROCESS 1
00019 #ifdef USE_SAMPLE_PROCESS
00020 
00021 
00022 #include "SpuSampleTaskProcess.h"
00023 #include <stdio.h>
00024 
00025 #ifdef __SPU__
00026 
00027 
00028 
00029 void    SampleThreadFunc(void* userPtr,void* lsMemory)
00030 {
00031         //do nothing
00032         printf("hello world\n");
00033 }
00034 
00035 
00036 void*   SamplelsMemoryFunc()
00037 {
00038         //don't create local store memory, just return 0
00039         return 0;
00040 }
00041 
00042 
00043 #else
00044 
00045 
00046 #include "btThreadSupportInterface.h"
00047 
00048 //#     include "SPUAssert.h"
00049 #include <string.h>
00050 
00051 
00052 
00053 extern "C" {
00054         extern char SPU_SAMPLE_ELF_SYMBOL[];
00055 }
00056 
00057 
00058 
00059 
00060 
00061 SpuSampleTaskProcess::SpuSampleTaskProcess(btThreadSupportInterface*    threadInterface,  int maxNumOutstandingTasks)
00062 :m_threadInterface(threadInterface),
00063 m_maxNumOutstandingTasks(maxNumOutstandingTasks)
00064 {
00065 
00066         m_taskBusy.resize(m_maxNumOutstandingTasks);
00067         m_spuSampleTaskDesc.resize(m_maxNumOutstandingTasks);
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 SpuSampleTaskProcess::~SpuSampleTaskProcess()
00084 {
00085         m_threadInterface->stopSPU();
00086         
00087 }
00088 
00089 
00090 
00091 void    SpuSampleTaskProcess::initialize()
00092 {
00093 #ifdef DEBUG_SPU_TASK_SCHEDULING
00094         printf("SpuSampleTaskProcess::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 SpuSampleTaskProcess::issueTask(void* sampleMainMemPtr,int sampleValue,int sampleCommand)
00109 {
00110 
00111 #ifdef DEBUG_SPU_TASK_SCHEDULING
00112         printf("SpuSampleTaskProcess::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         SpuSampleTaskDesc& taskDesc = m_spuSampleTaskDesc[m_currentTask];
00119         {
00120                 // send task description in event message
00121                 // no error checking here...
00122                 // but, currently, event queue can be no larger than NUM_WORKUNIT_TASKS.
00123         
00124                 taskDesc.m_mainMemoryPtr = reinterpret_cast<uint64_t>(sampleMainMemPtr);
00125                 taskDesc.m_sampleValue = sampleValue;
00126                 taskDesc.m_sampleCommand = sampleCommand;
00127 
00128                 //some bookkeeping to recognize finished tasks
00129                 taskDesc.m_taskId = m_currentTask;
00130         }
00131 
00132 
00133         m_threadInterface->sendRequest(1, (ppu_address_t) &taskDesc, m_currentTask);
00134 
00135         // if all tasks busy, wait for spu event to clear the task.
00136         
00137         if (m_numBusyTasks >= m_maxNumOutstandingTasks)
00138         {
00139                 unsigned int taskId;
00140                 unsigned int outputSize;
00141 
00142                 for (int i=0;i<m_maxNumOutstandingTasks;i++)
00143           {
00144                   if (m_taskBusy[i])
00145                   {
00146                           taskId = i;
00147                           break;
00148                   }
00149           }
00150                 m_threadInterface->waitForResponse(&taskId, &outputSize);
00151 
00152                 //printf("PPU: after issue, received event: %u %d\n", taskId, outputSize);
00153 
00154                 postProcess(taskId, outputSize);
00155 
00156                 m_taskBusy[taskId] = false;
00157 
00158                 m_numBusyTasks--;
00159         }
00160 
00161         // find new task buffer
00162         for (int i = 0; i < m_maxNumOutstandingTasks; i++)
00163         {
00164                 if (!m_taskBusy[i])
00165                 {
00166                         m_currentTask = i;
00167                         break;
00168                 }
00169         }
00170 }
00171 
00172 
00174 void SpuSampleTaskProcess::postProcess(int taskId, int outputSize)
00175 {
00176 
00177 }
00178 
00179 
00180 void SpuSampleTaskProcess::flush()
00181 {
00182 #ifdef DEBUG_SPU_TASK_SCHEDULING
00183         printf("\nSpuCollisionTaskProcess::flush()\n");
00184 #endif //DEBUG_SPU_TASK_SCHEDULING
00185         
00186 
00187         // all tasks are issued, wait for all tasks to be complete
00188         while(m_numBusyTasks > 0)
00189         {
00190 // Consolidating SPU code
00191           unsigned int taskId;
00192           unsigned int outputSize;
00193           
00194           for (int i=0;i<m_maxNumOutstandingTasks;i++)
00195           {
00196                   if (m_taskBusy[i])
00197                   {
00198                           taskId = i;
00199                           break;
00200                   }
00201           }
00202           {
00203                         
00204                   m_threadInterface->waitForResponse(&taskId, &outputSize);
00205           }
00206 
00207                 //printf("PPU: flushing, received event: %u %d\n", taskId, outputSize);
00208 
00209                 postProcess(taskId, outputSize);
00210 
00211                 m_taskBusy[taskId] = false;
00212 
00213                 m_numBusyTasks--;
00214         }
00215 
00216 
00217 }
00218 
00219 #endif
00220 
00221 
00222 #endif //USE_SAMPLE_PROCESS