1 /****************************************************************
\r
2 * Process Wrapper file
\r
3 * Creator: lschor, 2008-10-30
\r
4 * Description: Wrapper for a specific SPE process
\r
7 * - 2008-10-30: Created
\r
8 * - 2008-11-08: Update to Double Buffering
\r
9 * - 2008-11-15: Added Performance Estimation methods
\r
13 #include <spu_intrinsics.h>
\r
15 #include <spu_mfcio.h>
\r
21 // Include to allocate/free using for DMA transfers
\r
22 #include "lib/malloc_align.h"
\r
23 #include "lib/free_align.h"
\r
27 #include "lib/ProcessWrapper.h"
\r
28 #include "lib/estimation.h"
\r
31 static parm_context ctx __attribute__ ((aligned (128)));
\r
33 // Include of the process
\r
34 //#include "@PROCESSNAME@.c"
\r
37 int main(int speid , uint64_t argp)
\r
40 // Start the decrementer for time measurement
\r
41 spu_write_decrementer(MEASURE_START);
\r
45 double t_dol_spe = spu_read_decrementer();
\r
48 // reserve DMA tag ID
\r
50 if((tag_id=mfc_tag_reserve())==MFC_TAG_INVALID){
\r
51 printf("SPE: ERROR - can't reserve a tag ID\n"); return 1;
\r
55 // Get the context information for the whole system
\r
56 mfc_get((void*) &ctx, argp, sizeof(ctx), tag_id, 0, 0);
\r
57 mfc_write_tag_mask(1<<tag_id);
\r
58 mfc_read_tag_status_all();
\r
60 // Create the port / queue structs
\r
61 uint32_t port_id[roundDMA(ctx.number_of_ports)] __attribute__ ((aligned (128)));
\r
62 uint32_t port_queue_id[roundDMA(ctx.number_of_ports)] __attribute__ ((aligned (128)));
\r
64 // Copy the port list / queue list
\r
65 mfc_get((void*)port_id, ctx.port_id, sizeof(uint32_t) * roundDMA(ctx.number_of_ports), tag_id,0,0);
\r
66 mfc_get((void*)port_queue_id, ctx.port_queue_id, sizeof(uint32_t) * roundDMA(ctx.number_of_ports), tag_id,0,0);
\r
69 // Create the wrapper process
\r
70 ProcessWrapper *wrapper = (ProcessWrapper *)malloc(sizeof(ProcessWrapper));
\r
71 wrapper->number_of_ports = ctx.number_of_ports;
\r
72 wrapper->port_id = port_id;
\r
73 wrapper->port_queue_id = port_queue_id;
\r
74 wrapper->is_detached = 0;
\r
75 wrapper->name = (char *)_malloc_align((uint32_t)ctx.processNameLen, 4);
\r
76 mfc_get((void *)wrapper->name, ctx.processName, ctx.processNameLen, tag_id, 0, 0);
\r
80 //initialize the index array
\r
82 wrapper->index = (uint32_t *)malloc(4 * sizeof(int));
\r
83 for (i = 0; i < 4; i++)
\r
85 wrapper->index[i] = getIndex(wrapper->name, "_", i);
\r
88 // Init the queues for local buffering in the LS
\r
89 // Only the queues we really need
\r
93 DOLProcess* process;
\r
94 struct _local_states *state;
\r
96 process = (DOLProcess *)malloc(sizeof(DOLProcess));
\r
97 state = (struct _local_states *)malloc(sizeof(struct _local_states));
\r
99 memcpy(process, &@PROCESSNAME@, sizeof(DOLProcess));
\r
100 memcpy(state, @PROCESSNAME@.local, sizeof(struct _local_states));
\r
101 process->local = state;
\r
102 process->wptr = wrapper;
\r
104 // Init the process
\r
105 #ifdef MEASURE_DOL_INIT
\r
106 double t_dol_init = spu_read_decrementer();
\r
108 process->init(process);
\r
109 #ifdef MEASURE_DOL_INIT
\r
110 t_dol_init -= spu_read_decrementer();
\r
111 printf("DOL_INIT;%f\n",t_dol_init * 1 / MEASURE_CPU);
\r
115 while (!wrapper->is_detached)
\r
117 #ifdef MEASURE_DOL_FIRE
\r
118 double t_dol_fire = spu_read_decrementer();
\r
121 process->fire(process);
\r
123 #ifdef MEASURE_DOL_FIRE
\r
124 t_dol_fire -= spu_read_decrementer();
\r
125 printf("DOL_FIRE;%f\n",t_dol_fire * 1 / MEASURE_CPU);
\r
129 // Delete all malloc memory
\r
132 _free_align(wrapper->name);
\r
135 // release tag ID before exiting
\r
136 mfc_tag_release(tag_id);
\r
139 // Inform the main process that we have finished!
\r
140 spu_write_out_mbox((uint32_t)(4));
\r
143 t_dol_spe -= spu_read_decrementer();
\r
144 printf("DOL_SPE_@PROCESSNAME@;%f\n",t_dol_spe * 1 / MEASURE_CPU);
\r