1 /****************************************************************
\r
3 * Creator: lschor, 2008-10-30
\r
4 * Description: Defines Main functions for a FIFO in the Local Store of a SPE
\r
7 * - 2008-11-08: Created
\r
8 * - 2008-11-15: Added Performance Estimation methods
\r
11 #ifndef _PROCESS_FIFO_H_
\r
12 #define _PROCESS_FIFO_H_
\r
14 // Maximum data allowed in the FIFO
\r
15 static const int MAXELEMENT = 1024;
\r
17 // Varialbes to store a fifo-read process
\r
18 uint32_t tag_id_read = 99;
\r
19 uint32_t lenRead = 0;
\r
20 uint32_t queueRead = 0;
\r
23 char *locBuf[NUM_FIFO];
\r
24 int locBufCount[NUM_FIFO];
\r
25 int locBufStart[NUM_FIFO];
\r
27 // How many is free in a fifo
\r
28 uint32_t freespaceQueue(int queue)
\r
30 return MAXELEMENT - locBufCount[queue];
\r
38 for (j = 0; j < NUM_FIFO; j++)
\r
46 // Init a special queue
\r
47 void initLocBuf(int queue)
\r
49 locBuf[queue] = NULL;
\r
50 locBufCount[queue] = 0;
\r
51 locBufStart[queue] = 0;
\r
54 // Gives the memory of the buffers free
\r
58 for (j = 0; j < NUM_FIFO; j++)
\r
60 if (locBuf[j] != NULL)
\r
67 void updateLocBuf(int queue)
\r
69 // If the buffer is used the first time, allocate him
\r
70 if (locBuf[queue]== NULL)
\r
72 locBuf[queue] = (char *)malloc(MAXELEMENT * sizeof(char));
\r
74 #ifdef MEASURE_DOL_READ_START_DMA
\r
75 double t_dol_read_start_dma = spu_read_decrementer();
\r
78 // Double-Buffering --> Try to close the old read-process
\r
79 if (tag_id_read != 99)
\r
81 waittag(tag_id_read);
\r
82 // Write the data you read into the queue;
\r
85 #ifdef MEASURE_DOL_READ_DOUBLEBUF
\r
86 double t_dol_read_doublebuf = spu_read_decrementer();
\r
89 // Has to write all elements at the beginning or write all elements at the end of the buffer
\r
90 if (locBufStart[queueRead] + locBufCount[queueRead] > MAXELEMENT || locBufStart[queueRead] + locBufCount[queueRead] + lenRead < MAXELEMENT)
\r
92 memcpy(&(locBuf[queueRead][(locBufStart[queueRead] + locBufCount[queueRead]) % MAXELEMENT]), resultRead, lenRead);
\r
95 // Otherwise something at the end and something at the beginning
\r
98 // At the end of the buffer
\r
99 memcpy(&(locBuf[queueRead][(locBufStart[queueRead] + locBufCount[queueRead])]), resultRead, MAXELEMENT - locBufStart[queueRead] - locBufCount[queueRead]);
\r
101 // At the beginning
\r
102 memcpy(locBuf[queueRead], &(resultRead[MAXELEMENT - locBufStart[queueRead] - locBufCount[queueRead]]), lenRead - (MAXELEMENT - locBufStart[queueRead] - locBufCount[queueRead]));
\r
105 locBufCount[queueRead]+=lenRead;
\r
107 #ifdef MEASURE_DOL_READ_DOUBLEBUF
\r
108 t_dol_read_doublebuf -= spu_read_decrementer();
\r
109 printf("DOL_READ_DOUBLEBUF_DMA;%f\n",t_dol_read_doublebuf * 1 / MEASURE_CPU);
\r
112 mfc_tag_release(tag_id_read); // release tag ID before exiting
\r
113 _free_align(resultRead);
\r
115 // Send a okey about the data to the PPE
\r
116 spu_write_out_mbox((uint32_t)(SPE_READ_SUC << 28)); // stalls mailbox is full.
\r
120 uint32_t message = (SPE_READ_DEMAND << 28) | (queue << 16) | (freespaceQueue(queue));
\r
122 #ifdef MEASURE_DOL_READ_HANDSHAKE
\r
123 double t_dol_read_handshake = spu_read_decrementer();
\r
126 spu_write_out_mbox((uint32_t)(message));
\r
128 message = spu_read_in_mbox();
\r
129 uint32_t request = message >> 28;
\r
130 lenRead = (0xffff & message);
\r
132 if (request != (uint32_t) 1)
\r
137 if((tag_id_read=mfc_tag_reserve())==MFC_TAG_INVALID){
\r
138 printf("SPE: ERROR - can't reserve a tag ID\n"); return;
\r
141 // Wait for the response of the PPE --> The address where to read
\r
142 uint32_t ea_mfc_h, ea_mfc_l;
\r
145 ea_mfc_h = spu_read_in_mbox();
\r
146 ea_mfc_l = spu_read_in_mbox();
\r
147 ea_mfc = mfc_hl2ea(ea_mfc_h, ea_mfc_l);
\r
149 #ifdef MEASURE_DOL_READ_HANDSHAKE
\r
150 t_dol_read_handshake -= spu_read_decrementer();
\r
151 printf("DOL_READ_HANDSHAKE;%f\n",t_dol_read_handshake * 1 / MEASURE_CPU);
\r
154 #ifdef MEASURE_DOL_READ_START_DMA
\r
155 t_dol_read_start_dma -= spu_read_decrementer();
\r
156 printf("DOL_READ_START_DMA;%f\n",t_dol_read_start_dma * 1 / MEASURE_CPU);
\r
159 resultRead = (char *)_malloc_align(lenRead, 4);
\r
161 #ifdef MEASURE_DOL_READ_DMA
\r
162 double t_dol_read_dma = spu_read_decrementer();
\r
165 // Read the data from the address we got from the PPE
\r
166 mfc_get(&(resultRead[0]), ea_mfc, lenRead, tag_id_read, 0, 0);
\r
167 #ifdef MEASURE_DOL_READ_DMA
\r
168 t_dol_read_dma -= spu_read_decrementer();
\r
169 printf("DOL_READ_DMA;%f\n",t_dol_read_dma * 1 / MEASURE_CPU);
\r
172 queueRead = queue;
\r
175 // Read from the local buffer
\r
176 void readLocBuf(int queue, void *destination, int len)
\r
178 #ifdef MEASURE_DOL_READ_LOCBUF
\r
179 double t_dol_read_locbuf = spu_read_decrementer();
\r
183 char* buffer = (char*) destination;
\r
186 while (count < len)
\r
188 newLen = (len - count) > MAXELEMENT? MAXELEMENT : len - count;
\r
190 while (locBufCount[queue] < newLen)
\r
192 updateLocBuf(queue);
\r
195 // Can directly read all elements from the end of the buffer
\r
196 if (locBufStart[queue] + newLen < MAXELEMENT)
\r
198 memcpy(buffer, &(locBuf[queue][locBufStart[queue]]), newLen);
\r
201 // Has to write from the end and from the beginning of the buffer
\r
204 memcpy(&(buffer[count]), &(locBuf[queue][locBufStart[queue]]), MAXELEMENT - locBufStart[queue]);
\r
205 memcpy(&(buffer[count + MAXELEMENT - locBufStart[queue]]), locBuf[queue], newLen - MAXELEMENT + locBufStart[queue]);
\r
208 locBufCount[queue] -= newLen;
\r
209 locBufStart[queue] = (locBufStart[queue] + newLen) % MAXELEMENT;
\r
212 #ifdef MEASURE_DOL_READ_LOCBUF
\r
213 t_dol_read_locbuf -= spu_read_decrementer();
\r
214 printf("DOL_READ_LOCBUF;%f\n",t_dol_read_locbuf * 1 / MEASURE_CPU);
\r
219 #endif // _PROCESS_FIFO_H_
\r