--- /dev/null
+/**************************************************************** \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