Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifdef USE_LIBSPE2
00017
00018 #include "SpuLibspe2Support.h"
00019
00020
00021
00022
00023
00025 SpuLibspe2Support::SpuLibspe2Support(spe_program_handle_t *speprog, int numThreads)
00026 {
00027 this->program = speprog;
00028 this->numThreads = ((numThreads <= spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1)) ? numThreads : spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1));
00029 }
00030
00032 SpuLibspe2Support::~SpuLibspe2Support()
00033 {
00034
00035 stopSPU();
00036 }
00037
00038
00039
00041 void SpuLibspe2Support::sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1)
00042 {
00043 spe_context_ptr_t context;
00044
00045 switch (uiCommand)
00046 {
00047 case CMD_SAMPLE_TASK_COMMAND:
00048 {
00049
00050 SpuSampleTaskDesc* taskDesc = (SpuSampleTaskDesc*) uiArgument0;
00051
00052 btAssert(taskDesc->m_taskId<m_activeSpuStatus.size());
00053
00054
00055 btSpuStatus& spuStatus = m_activeSpuStatus[taskDesc->m_taskId];
00056
00057
00058 spuStatus.m_commandId = uiCommand;
00059 spuStatus.m_status = Spu_Status_Occupied;
00060 spuStatus.m_taskDesc.p = taskDesc;
00061
00062
00063 context = data[taskDesc->m_taskId].context;
00064
00065
00066 taskDesc->m_mainMemoryPtr = reinterpret_cast<uint64_t> (spuStatus.m_lsMemory.p);
00067
00068
00069 break;
00070 }
00071 case CMD_GATHER_AND_PROCESS_PAIRLIST:
00072 {
00073
00074 SpuGatherAndProcessPairsTaskDesc* taskDesc = (SpuGatherAndProcessPairsTaskDesc*) uiArgument0;
00075
00076 btAssert(taskDesc->taskId<m_activeSpuStatus.size());
00077
00078
00079 btSpuStatus& spuStatus = m_activeSpuStatus[taskDesc->taskId];
00080
00081
00082 spuStatus.m_commandId = uiCommand;
00083 spuStatus.m_status = Spu_Status_Occupied;
00084 spuStatus.m_taskDesc.p = taskDesc;
00085
00086
00087 context = data[taskDesc->taskId].context;
00088
00089
00090 taskDesc->m_lsMemory = (CollisionTask_LocalStoreMemory*)spuStatus.m_lsMemory.p;
00091
00092 break;
00093 }
00094 default:
00095 {
00097 btAssert(0);
00098 }
00099
00100 };
00101
00102
00103
00104 unsigned int event = Spu_Mailbox_Event_Task;
00105 spe_in_mbox_write(context, &event, 1, SPE_MBOX_ANY_NONBLOCKING);
00106
00107 }
00108
00110 void SpuLibspe2Support::waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1)
00111 {
00113
00115
00116 btAssert(m_activeSpuStatus.size());
00117
00118
00119 int last = -1;
00120
00121
00122 while(last < 0)
00123 {
00124 for (int i=0;i<m_activeSpuStatus.size();i++)
00125 {
00126 if ( m_activeSpuStatus[i].m_status == Spu_Status_Free)
00127 {
00128 last = i;
00129 break;
00130 }
00131 }
00132 if(last < 0)
00133 sched_yield();
00134 }
00135
00136
00137
00138 btSpuStatus& spuStatus = m_activeSpuStatus[last];
00139
00141 btAssert(last>=0);
00142
00143
00144
00145 *puiArgument0 = spuStatus.m_taskId;
00146 *puiArgument1 = spuStatus.m_status;
00147
00148
00149 }
00150
00151
00152 void SpuLibspe2Support::startSPU()
00153 {
00154 this->internal_startSPU();
00155 }
00156
00157
00158
00160 void SpuLibspe2Support::internal_startSPU()
00161 {
00162 m_activeSpuStatus.resize(numThreads);
00163
00164
00165 for (int i=0; i < numThreads; i++)
00166 {
00167
00168 if(data[i].context == NULL)
00169 {
00170
00171
00172 if ((data[i].context = spe_context_create(0, NULL)) == NULL)
00173 {
00174 perror ("Failed creating context");
00175 exit(1);
00176 }
00177
00178
00179 if(spe_program_load(data[i].context, this->program))
00180 {
00181 perror ("Failed loading program");
00182 exit(1);
00183 }
00184
00185 m_activeSpuStatus[i].m_status = Spu_Status_Startup;
00186 m_activeSpuStatus[i].m_taskId = i;
00187 m_activeSpuStatus[i].m_commandId = 0;
00188 m_activeSpuStatus[i].m_lsMemory.p = NULL;
00189
00190
00191 data[i].entry = SPE_DEFAULT_ENTRY;
00192 data[i].flags = 0;
00193 data[i].argp.p = &m_activeSpuStatus[i];
00194 data[i].envp.p = NULL;
00195
00196
00197 if (pthread_create(&data[i].pthread, NULL, &ppu_pthread_function, &(data[i]) ))
00198 {
00199 perror ("Failed creating thread");
00200 exit(1);
00201 }
00202
00203
00204
00205
00206
00207 }
00208 }
00209
00210
00211 for (int i=0; i < numThreads; i++)
00212 {
00213 if(data[i].context != NULL)
00214 {
00215 while( m_activeSpuStatus[i].m_status == Spu_Status_Startup)
00216 {
00217
00218 sched_yield();
00219 }
00220 printf("Spu %d is ready\n", i);
00221 }
00222 }
00223 }
00224
00226 void SpuLibspe2Support::stopSPU()
00227 {
00228
00229 int i;
00230 for ( i = 0; i < this->numThreads; i++ )
00231 {
00232
00233 unsigned int event = Spu_Mailbox_Event_Shutdown;
00234 spe_context_ptr_t context = data[i].context;
00235 spe_in_mbox_write(context, &event, 1, SPE_MBOX_ALL_BLOCKING);
00236 pthread_join (data[i].pthread, NULL);
00237
00238 }
00239
00240 spe_image_close(program);
00241
00242 for ( i = 0; i < this->numThreads; i++ )
00243 {
00244 if(data[i].context != NULL)
00245 {
00246 spe_context_destroy (data[i].context);
00247 }
00248 }
00249
00250 m_activeSpuStatus.clear();
00251
00252 }
00253
00254
00255
00256 #endif //USE_LIBSPE2
00257