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