X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fcbe%2Flib%2FProcessFifo.h;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fcbe%2Flib%2FProcessFifo.h;h=8054cd2c13e5c69fb31620ffae081a7670f81778;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/cbe/lib/ProcessFifo.h b/dol/src/dol/visitor/cbe/lib/ProcessFifo.h new file mode 100644 index 0000000..8054cd2 --- /dev/null +++ b/dol/src/dol/visitor/cbe/lib/ProcessFifo.h @@ -0,0 +1,219 @@ +/**************************************************************** + * FIFO Functions + * Creator: lschor, 2008-10-30 + * Description: Defines Main functions for a FIFO in the Local Store of a SPE + * + * Revision: + * - 2008-11-08: Created + * - 2008-11-15: Added Performance Estimation methods + */ + +#ifndef _PROCESS_FIFO_H_ +#define _PROCESS_FIFO_H_ + +// Maximum data allowed in the FIFO +static const int MAXELEMENT = 1024; + +// Varialbes to store a fifo-read process +uint32_t tag_id_read = 99; +uint32_t lenRead = 0; +uint32_t queueRead = 0; +char * resultRead; + +char *locBuf[NUM_FIFO]; +int locBufCount[NUM_FIFO]; +int locBufStart[NUM_FIFO]; + +// How many is free in a fifo +uint32_t freespaceQueue(int queue) +{ + return MAXELEMENT - locBufCount[queue]; +} + + +// Init all fifos +void initQueues() +{ + int j; + for (j = 0; j < NUM_FIFO; j++) + { + locBuf[j] = NULL; + locBufCount[j] = 0; + locBufStart[j] = 0; + } +} + +// Init a special queue +void initLocBuf(int queue) +{ + locBuf[queue] = NULL; + locBufCount[queue] = 0; + locBufStart[queue] = 0; +} + +// Gives the memory of the buffers free +void deinitLocBuf() +{ + int j; + for (j = 0; j < NUM_FIFO; j++) + { + if (locBuf[j] != NULL) + { + free(locBuf[j]); + } + } +} + +void updateLocBuf(int queue) +{ + // If the buffer is used the first time, allocate him + if (locBuf[queue]== NULL) + { + locBuf[queue] = (char *)malloc(MAXELEMENT * sizeof(char)); + } +#ifdef MEASURE_DOL_READ_START_DMA + double t_dol_read_start_dma = spu_read_decrementer(); +#endif + + // Double-Buffering --> Try to close the old read-process + if (tag_id_read != 99) + { + waittag(tag_id_read); + // Write the data you read into the queue; + int i; + + #ifdef MEASURE_DOL_READ_DOUBLEBUF + double t_dol_read_doublebuf = spu_read_decrementer(); + #endif + + // Has to write all elements at the beginning or write all elements at the end of the buffer + if (locBufStart[queueRead] + locBufCount[queueRead] > MAXELEMENT || locBufStart[queueRead] + locBufCount[queueRead] + lenRead < MAXELEMENT) + { + memcpy(&(locBuf[queueRead][(locBufStart[queueRead] + locBufCount[queueRead]) % MAXELEMENT]), resultRead, lenRead); + } + + // Otherwise something at the end and something at the beginning + else + { + // At the end of the buffer + memcpy(&(locBuf[queueRead][(locBufStart[queueRead] + locBufCount[queueRead])]), resultRead, MAXELEMENT - locBufStart[queueRead] - locBufCount[queueRead]); + + // At the beginning + memcpy(locBuf[queueRead], &(resultRead[MAXELEMENT - locBufStart[queueRead] - locBufCount[queueRead]]), lenRead - (MAXELEMENT - locBufStart[queueRead] - locBufCount[queueRead])); + } + + locBufCount[queueRead]+=lenRead; + + #ifdef MEASURE_DOL_READ_DOUBLEBUF + t_dol_read_doublebuf -= spu_read_decrementer(); + printf("DOL_READ_DOUBLEBUF_DMA;%f\n",t_dol_read_doublebuf * 1 / MEASURE_CPU); + #endif + + mfc_tag_release(tag_id_read); // release tag ID before exiting + _free_align(resultRead); + + // Send a okey about the data to the PPE + spu_write_out_mbox((uint32_t)(SPE_READ_SUC << 28)); // stalls mailbox is full. + tag_id_read = 99; + } + + uint32_t message = (SPE_READ_DEMAND << 28) | (queue << 16) | (freespaceQueue(queue)); + +#ifdef MEASURE_DOL_READ_HANDSHAKE + double t_dol_read_handshake = spu_read_decrementer(); +#endif + + spu_write_out_mbox((uint32_t)(message)); + + message = spu_read_in_mbox(); + uint32_t request = message >> 28; + lenRead = (0xffff & message); + + if (request != (uint32_t) 1) + { + return; + } + + if((tag_id_read=mfc_tag_reserve())==MFC_TAG_INVALID){ + printf("SPE: ERROR - can't reserve a tag ID\n"); return; + } + + // Wait for the response of the PPE --> The address where to read + 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_READ_HANDSHAKE + t_dol_read_handshake -= spu_read_decrementer(); + printf("DOL_READ_HANDSHAKE;%f\n",t_dol_read_handshake * 1 / MEASURE_CPU); +#endif + +#ifdef MEASURE_DOL_READ_START_DMA + t_dol_read_start_dma -= spu_read_decrementer(); + printf("DOL_READ_START_DMA;%f\n",t_dol_read_start_dma * 1 / MEASURE_CPU); +#endif + + resultRead = (char *)_malloc_align(lenRead, 4); + +#ifdef MEASURE_DOL_READ_DMA + double t_dol_read_dma = spu_read_decrementer(); +#endif + + // Read the data from the address we got from the PPE + mfc_get(&(resultRead[0]), ea_mfc, lenRead, tag_id_read, 0, 0); +#ifdef MEASURE_DOL_READ_DMA + t_dol_read_dma -= spu_read_decrementer(); + printf("DOL_READ_DMA;%f\n",t_dol_read_dma * 1 / MEASURE_CPU); +#endif + + queueRead = queue; +} + +// Read from the local buffer +void readLocBuf(int queue, void *destination, int len) +{ +#ifdef MEASURE_DOL_READ_LOCBUF + double t_dol_read_locbuf = spu_read_decrementer(); +#endif + int count = 0; + int newLen = 0; + char* buffer = (char*) destination; + int i; + + while (count < len) + { + newLen = (len - count) > MAXELEMENT? MAXELEMENT : len - count; + + while (locBufCount[queue] < newLen) + { + updateLocBuf(queue); + } + + // Can directly read all elements from the end of the buffer + if (locBufStart[queue] + newLen < MAXELEMENT) + { + memcpy(buffer, &(locBuf[queue][locBufStart[queue]]), newLen); + } + + // Has to write from the end and from the beginning of the buffer + else + { + memcpy(&(buffer[count]), &(locBuf[queue][locBufStart[queue]]), MAXELEMENT - locBufStart[queue]); + memcpy(&(buffer[count + MAXELEMENT - locBufStart[queue]]), locBuf[queue], newLen - MAXELEMENT + locBufStart[queue]); + } + + locBufCount[queue] -= newLen; + locBufStart[queue] = (locBufStart[queue] + newLen) % MAXELEMENT; + count += newLen; + } +#ifdef MEASURE_DOL_READ_LOCBUF + t_dol_read_locbuf -= spu_read_decrementer(); + printf("DOL_READ_LOCBUF;%f\n",t_dol_read_locbuf * 1 / MEASURE_CPU); +#endif +} + + +#endif // _PROCESS_FIFO_H_