X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fcbe%2Flib%2FProcessWrapper.h;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fcbe%2Flib%2FProcessWrapper.h;h=c06075dde0148b12f115563b96fe14a0101b14f8;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/cbe/lib/ProcessWrapper.h b/dol/src/dol/visitor/cbe/lib/ProcessWrapper.h new file mode 100644 index 0000000..c06075d --- /dev/null +++ b/dol/src/dol/visitor/cbe/lib/ProcessWrapper.h @@ -0,0 +1,248 @@ +/**************************************************************** + * Process Wrapper Functions + * Creator: lschor, 2008-10-30 + * Description: General process wrapper file, includes DOL_read and DOL_write as main functions + * + * Revision: + * - 2008-10-30: Created + * - 2008-11-08: Update to Double Buffering + * - 2008-11-15: Added Performance Estimation methods + */ + +#ifndef __PROCESS_WRAPPER_H__ +#define __PROCESS_WRAPPER_H__ + +#include +#include +#include +#include +#include // Used for va_list +#include +#include "lib/malloc_align.h" // Malloc for DMA +#include "lib/free_align.h" // Free for DMA +#include "dol.h" +#include "common.h" +#include "estimation.h" + +//Cell Macros +#define waittag(tag_id) mfc_write_tag_mask(1<wptr))->index[dimension] + +#define CREATEPORTVAR(name) \ + int name + +#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \ + createPort(&port, base, number_of_indices, index_range_pairs) + +// Include the FIFO Functions +#include "lib/ProcessFifo.h" + +// Include some help functions +#include "lib/ProcessWrapperHelp.h" + +// Struct for a process +typedef struct _process_wrapper { + char* name; + uint32_t* index; + uint32_t is_detached; + uint32_t* port_id; + uint32_t* port_queue_id; + uint32_t number_of_ports; +} ProcessWrapper; + +// Tag address for the write process +uint32_t tag_id_write = 99; + +// Pointer to the current data buffer +char * resultWrite; + +/** + * Finish a DOL_write process + */ +void finish_DOL_write() +{ + if (tag_id_write != 99) + { + #ifdef MEASURE_DOL_WRITE_FINISH + double t_dol_write_finish = spu_read_decrementer(); + #endif + + // Wait until the write process is finished + waittag(tag_id_write); + mfc_tag_release(tag_id_write); // release tag ID before exiting + _free_align(resultWrite); + // Send a okey about the data to the PPE + spu_write_out_mbox((uint32_t)(SPE_WRITE_SUC << 28)); // stalls mailbox is full. + tag_id_write = 99; + //queueWrite = -1; + + #ifdef MEASURE_DOL_WRITE_FINISH + t_dol_write_finish -= spu_read_decrementer(); + printf("DOL_WRITE_FINISH;%f\n",t_dol_write_finish * 1 / MEASURE_CPU); + #endif + + } +} + +/** + * Read from the FIFO + */ +void DOL_read(void *port, void *buf, int len, DOLProcess *process) +{ +#ifdef MEASURE_DOL_READ + double t_dol_read = spu_read_decrementer(); +#endif + + ProcessWrapper* process_wrapper = (ProcessWrapper*)process->wptr; + int i; + + for (i = 0; i < process_wrapper->number_of_ports; i++) + { + if (process_wrapper->port_id[i] == (int)port) + { + int queue = process_wrapper->port_queue_id[i]; + + finish_DOL_write(); + + // Try to get new data into the local Buffer + updateLocBuf(queue); + + // Read from the Buffer + readLocBuf(queue, buf, len); + + break; + } + } +#ifdef MEASURE_DOL_READ + t_dol_read -= spu_read_decrementer(); + printf("DOL_READ;%f\n",t_dol_read * 1 / MEASURE_CPU); +#endif + +} + + +/** + * Write data into the FIFO + */ +void DOL_write(void *port, void *buf, int len, DOLProcess *process) +{ +#ifdef MEASURE_DOL_WRITE + double t_dol_write = spu_read_decrementer(); +#endif + + ProcessWrapper* process_wrapper = (ProcessWrapper*)process->wptr; + int i; + + for (i = 0; i < process_wrapper->number_of_ports; i++) + { + if (process_wrapper->port_id[i] == (int)port) + { + // This is our queue + int queue = process_wrapper->port_queue_id[i]; + + #ifdef MEASURE_DOL_WRITE_START_DMA + double t_dol_write_start_dma = spu_read_decrementer(); + #endif + + // There has been a writing process. Is it already finished? + finish_DOL_write(); + + // Create the new write process + + // reserve DMA tag ID + if((tag_id_write=mfc_tag_reserve())==MFC_TAG_INVALID){ + printf("SPE: ERROR - can't reserve a tag ID\n"); return; + } + + // Create the message we like to send, format: + // 4 bit: code (total 16 possibilities) + // 12 bit: queue (total 4096 possibilities) + // 16 bit: len (total maximal size of 512 KB which could be send) + uint32_t message = (SPE_WRITE_DEMAND << 28) | (queue << 16) | (len); + + #ifdef MEASURE_DOL_WRITE_HANDSHAKE + double t_dol_write_handshake = spu_read_decrementer(); + #endif + // Demand the PPE for an address + spu_write_out_mbox(message); + + // Copy the data into the right data-alignment + resultWrite = (char *)_malloc_align(roundDMA(len), 4); + memcpy(resultWrite, buf, len); + + // Is there enough free space to write into the queues? + uint32_t messageIn = spu_read_in_mbox(); + uint32_t request = messageIn >> 28; + + while (request != (uint32_t) 1) + { + spu_write_out_mbox(message); + messageIn = spu_read_in_mbox(); + request = messageIn >> 28; + } + + // Wait for the response of the PPE, i.e. the address for the FIFO element + uint32_t ea_mfc_h, ea_mfc_l; + uint64_t ea_mfc; + ea_mfc_h = spu_read_in_mbox(); + ea_mfc_l = spu_read_in_mbox(); + ea_mfc = mfc_hl2ea(ea_mfc_h, ea_mfc_l); + + #ifdef MEASURE_DOL_WRITE_HANDSHAKE + t_dol_write_handshake -= spu_read_decrementer(); + printf("DOL_WRITE_HANDSHAKE;%f\n",t_dol_write_handshake * 1 / MEASURE_CPU); + #endif + + + #ifdef MEASURE_DOL_WRITE_START_DMA + t_dol_write_start_dma -= spu_read_decrementer(); + printf("DOL_WRITE_START_DMA;%f\n",t_dol_write_start_dma * 1 / MEASURE_CPU); + #endif + + #ifdef MEASURE_DOL_WRITE_DMA + double t_dol_write_dma = spu_read_decrementer(); + #endif + + // Write the data to the address we got from the PPE + mfc_put((void *)&(resultWrite[0]), ea_mfc, roundDMA(len), tag_id_write, 0, 0); + + #ifdef MEASURE_DOL_WRITE_DMA + t_dol_write_dma -= spu_read_decrementer(); + printf("DOL_WRITE_DMA;%f\n",t_dol_write_dma * 1 / MEASURE_CPU); + #endif + + + break; + } + } +#ifdef MEASURE_DOL_WRITE + t_dol_write -= spu_read_decrementer(); + printf("DOL_WRITE;%f\n",t_dol_write * 1 / MEASURE_CPU); +#endif +} + +/** + * Detach the DOL Process + */ +void DOL_detach(DOLProcess *process) { + //printf("[%s] DOL_detach.\n", (char*)(((ProcessWrapper*)process->wptr)->name)); + + // Check if all write processes are finished + if (tag_id_write != 99) + { + waittag(tag_id_write); + mfc_tag_release(tag_id_write); // release tag ID before exiting + _free_align(resultWrite); + spu_write_out_mbox((uint32_t)(2 << 28)); // stalls mailbox is full. + } + + uint32_t message = (SPE_DETACH << 28); + spu_write_out_mbox(message); + deinitLocBuf(); + ((ProcessWrapper*)process->wptr)->is_detached = 1; +} + +#endif