Changeset 461 for soft/giet_vm/giet_libs/mwmr_channel.c
- Timestamp:
- Dec 5, 2014, 4:02:27 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_libs/mwmr_channel.c
r450 r461 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 8 #include <mwmr_channel.h> 9 #include <stdio.h> 8 #include "mwmr_channel.h" 9 #include "giet_config.h" 10 #include "stdio.h" 11 #include "user_lock.h" 10 12 11 13 ////////////////////////////////////// 12 14 void mwmr_init( mwmr_channel_t* mwmr, 13 unsigned int width, // numer of words per item 14 unsigned int items ) // max number of items 15 { 16 if ( ((items * width)) > 1018 ) 17 giet_exit("[MWMR ERROR] in mwmr_init() : buffer size larger than 4072 bytes\n"); 15 unsigned int* buffer, // buffer base address 16 unsigned int width, // number of words per item 17 unsigned int nitems ) // max number of items 18 { 19 20 #if GIET_DEBUG_MWMR 21 unsigned int x; 22 unsigned int y; 23 unsigned int lpid; 24 giet_proc_xyp( &x, &y, &lpid ); 25 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] initialises fifo %x / " 26 " buffer = %x / width = %d / nitems = %d\n", 27 x, y, lpid, (unsigned int)mwmr, (unsigned int)buffer, width, nitems ); 28 #endif 18 29 19 30 mwmr->ptw = 0; … … 21 32 mwmr->sts = 0; 22 33 mwmr->width = width; 23 mwmr->depth = width * items; 24 mwmr->lock = 0; 25 26 #if GIET_DEBUG_MWMR 27 giet_shr_printf("[MWMR DEBUG] Initialise MWMR channel\n" 28 " - vbase = %x\n" 29 " - width = %d\n" 30 " - depth = %d\n", 31 (unsigned int)mwmr, width, items ); 32 #endif 34 mwmr->depth = width * nitems; 35 mwmr->data = buffer; 36 37 lock_init( &mwmr->lock ); 33 38 } 34 35 36 ///////////////////////////////////////////////////37 static void mwmr_lock_acquire( unsigned int* lock )38 {39 register unsigned int* plock = lock;40 register unsigned int delay = 100;41 asm volatile (42 "1: \n"43 "ll $2, 0(%0) \n" /* $2 <= lock current value */44 "bnez $2, 2f \n" /* retry after delay if lock busy */45 "li $3, 1 \n" /* $3 <= argument for sc */46 "sc $3, 0(%0) \n" /* try to get lock */47 "bnez $3, 3f \n" /* exit if atomic */48 "2: \n"49 "move $4, %1 \n" /* $4 <= delay */50 "4: \n"51 "beqz $4, 4b \n" /* test end delay */52 "addi $4, $4, -1 \n" /* $4 <= $4 - 1 */53 "j 1b \n" /* retry ll */54 "nop \n"55 "3: \n"56 :57 :"r"(plock), "r"(delay)58 :"$2", "$3", "$4");59 }60 39 61 40 62 41 /////////////////////////////////////////////////// 63 42 unsigned int nb_mwmr_write( mwmr_channel_t * mwmr, 64 unsigned int * buffer, 65 unsigned int nitems) 66 { 67 unsigned int x; 43 unsigned int * buffer, 44 unsigned int items) 45 { 46 47 #if GIET_DEBUG_MWMR 48 unsigned int x; 49 unsigned int y; 50 unsigned int lpid; 51 giet_proc_xyp( &x, &y, &lpid ); 52 #endif 53 54 unsigned int n; 68 55 unsigned int spaces; // number of empty slots (in words) 69 56 unsigned int nwords; // requested transfer length (in words) … … 73 60 unsigned int ptw; // channel ptw 74 61 75 if ( nitems == 0) return 0;62 if (items == 0) return 0; 76 63 77 64 // get the lock 78 mwmr_lock_acquire(&mwmr->lock);65 lock_acquire( &mwmr->lock ); 79 66 80 67 // access fifo status 81 depth = mwmr->depth;82 width = mwmr->width;83 sts = mwmr->sts;84 ptw = mwmr->ptw;68 depth = mwmr->depth; 69 width = mwmr->width; 70 sts = mwmr->sts; 71 ptw = mwmr->ptw; 85 72 spaces = depth - sts; 86 nwords = width * nitems;87 88 if (spaces >= nwords) // transfer nitems, release lock and return73 nwords = width * items; 74 75 if (spaces >= nwords) // transfer items, release lock and return 89 76 { 90 for ( x = 0; x < nwords; x++)91 { 92 mwmr->data[ptw] = buffer[ x];77 for (n = 0; n < nwords; n++) 78 { 79 mwmr->data[ptw] = buffer[n]; 93 80 if ((ptw + 1) == depth) ptw = 0; 94 81 else ptw = ptw + 1; … … 96 83 mwmr->sts = mwmr->sts + nwords; 97 84 mwmr->ptw = ptw; 98 mwmr->lock = 0; 99 return nitems; 85 86 #if GIET_DEBUG_MWMR 87 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n", 88 x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts ); 89 #endif 90 91 lock_release( &mwmr->lock ); 92 return items; 100 93 } 101 94 else if (spaces < width) // release lock and return 102 95 { 103 mwmr->lock = 0;96 lock_release( &mwmr->lock ); 104 97 return 0; 105 98 } … … 107 100 { 108 101 nwords = (spaces / width) * width; // integer number of items 109 for ( x = 0; x < nwords; x++)110 { 111 mwmr->data[ptw] = buffer[ x];102 for (n = 0; n < nwords; n++) 103 { 104 mwmr->data[ptw] = buffer[n]; 112 105 if ((ptw + 1) == depth) ptw = 0; 113 106 else ptw = ptw + 1; … … 115 108 mwmr->sts = sts + nwords; 116 109 mwmr->ptw = ptw; 117 mwmr->lock = 0; 110 111 #if GIET_DEBUG_MWMR 112 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n", 113 x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts ); 114 #endif 115 116 lock_release( &mwmr->lock ); 118 117 return (nwords / width); 119 118 } … … 125 124 unsigned int nb_mwmr_read( mwmr_channel_t * mwmr, 126 125 unsigned int * buffer, 127 unsigned int nitems) 128 { 129 unsigned int x; 130 unsigned int nwords; // requested transfer length (in words) 131 unsigned int depth; // channel depth (in words) 132 unsigned int width; // channel width (in words) 133 unsigned int sts; // channel sts 134 unsigned int ptr; // channel ptr 135 136 if (nitems == 0) return 0; 126 unsigned int items) 127 { 128 129 #if GIET_DEBUG_MWMR 130 unsigned int x; 131 unsigned int y; 132 unsigned int lpid; 133 giet_proc_xyp( &x, &y, &lpid ); 134 #endif 135 136 unsigned int n; 137 unsigned int nwords; // requested transfer length (words) 138 unsigned int depth; // channel depth (words) 139 unsigned int width; // channel width (words) 140 unsigned int sts; // channel sts (words) 141 unsigned int ptr; // channel ptr (words) 142 143 if (items == 0) return 0; 137 144 138 145 // get the lock 139 mwmr_lock_acquire(&mwmr->lock);146 lock_acquire( &mwmr->lock ); 140 147 141 148 // access fifo status 142 depth = mwmr->depth;143 width = mwmr->width;144 sts = mwmr->sts;145 ptr = mwmr->ptr;146 nwords = width * nitems;147 148 if (sts >= nwords) // transfer nitems, release lock and return149 { 150 for ( x = 0; x < nwords; x++)151 { 152 buffer[ x] = mwmr->data[ptr];149 depth = mwmr->depth; 150 width = mwmr->width; 151 sts = mwmr->sts; 152 ptr = mwmr->ptr; 153 nwords = width * items; 154 155 if (sts >= nwords) // transfer items, release lock and return 156 { 157 for (n = 0; n < nwords; n++) 158 { 159 buffer[n] = mwmr->data[ptr]; 153 160 if ((ptr + 1) == depth) ptr = 0; 154 161 else ptr = ptr + 1; … … 156 163 mwmr->sts = mwmr->sts - nwords; 157 164 mwmr->ptr = ptr; 158 mwmr->lock = 0; 159 return nitems; 165 166 #if GIET_DEBUG_MWMR 167 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n", 168 x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts ); 169 #endif 170 171 lock_release( &mwmr->lock ); 172 return items; 160 173 } 161 174 else if (sts < width) // release lock and return 162 175 { 163 mwmr->lock = 0; 176 177 #if GIET_DEBUG_MWMR 178 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read nothing in fifo %x : sts = %d\n", 179 x, y, lpid, (unsigned int)mwmr, mwmr->sts ); 180 #endif 181 182 lock_release( &mwmr->lock ); 164 183 return 0; 165 184 } … … 167 186 { 168 187 nwords = (sts / width) * width; // integer number of items 169 for ( x = 0 ; x < nwords ; x++)170 { 171 buffer[ x] = mwmr->data[ptr];188 for (n = 0 ; n < nwords ; n++) 189 { 190 buffer[n] = mwmr->data[ptr]; 172 191 if ((ptr + 1) == depth) ptr = 0; 173 192 else ptr = ptr + 1; … … 175 194 mwmr->sts = sts - nwords; 176 195 mwmr->ptr = ptr; 177 mwmr->lock = 0; 196 197 #if GIET_DEBUG_MWMR 198 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n", 199 x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts ); 200 #endif 201 202 lock_release( &mwmr->lock ); 178 203 return (nwords / width); 179 204 } … … 185 210 void mwmr_write( mwmr_channel_t * mwmr, 186 211 unsigned int * buffer, 187 unsigned int nitems ) 188 { 189 unsigned int x; 212 unsigned int items ) 213 { 214 215 #if GIET_DEBUG_MWMR 216 unsigned int x; 217 unsigned int y; 218 unsigned int lpid; 219 giet_proc_xyp( &x, &y, &lpid ); 220 #endif 221 222 unsigned int n; 190 223 unsigned int spaces; // number of empty slots (in words) 191 224 unsigned int nwords; // requested transfer length (in words) … … 195 228 unsigned int ptw; // channel ptw 196 229 197 if ( nitems == 0) return;230 if (items == 0) return; 198 231 199 232 while (1) 200 233 { 201 234 // get the lock 202 mwmr_lock_acquire(&mwmr->lock);235 lock_acquire( &mwmr->lock ); 203 236 204 237 // compute spaces and nwords … … 208 241 ptw = mwmr->ptw; 209 242 spaces = depth - sts; 210 nwords = width * nitems;243 nwords = width * items; 211 244 212 245 if (spaces >= nwords) // write nwords, release lock and return 213 246 { 214 for ( x = 0; x < nwords; x++)247 for (n = 0; n < nwords; n++) 215 248 { 216 mwmr->data[ptw] = buffer[ x];249 mwmr->data[ptw] = buffer[n]; 217 250 if ((ptw + 1) == depth) ptw = 0; 218 251 else ptw = ptw + 1; … … 220 253 mwmr->ptw = ptw; 221 254 mwmr->sts = sts + nwords; 222 mwmr->lock = 0; 255 256 #if GIET_DEBUG_MWMR 257 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n", 258 x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts ); 259 #endif 260 261 lock_release( &mwmr->lock ); 223 262 return; 224 263 } 225 else if (spaces < width) // release lock and deschedule226 { 227 mwmr->lock = 0;228 } 229 else // write as many items as possible, release lock and deschedule264 else if (spaces < width) // release lock and retry 265 { 266 lock_release( &mwmr->lock ); 267 } 268 else // write as many items as possible, release lock and retry 230 269 { 231 270 nwords = (spaces / width) * width; // integer number of items 232 for ( x = 0; x < nwords; x++)271 for (n = 0; n < nwords; n++) 233 272 { 234 mwmr->data[ptw] = buffer[ x];273 mwmr->data[ptw] = buffer[n]; 235 274 if ((ptw + 1) == depth) ptw = 0; 236 275 else ptw = ptw + 1; … … 239 278 mwmr->ptw = ptw; 240 279 buffer = buffer + nwords; 241 nitems = nitems - (nwords/width); 242 mwmr->lock = 0; 243 } 244 giet_context_switch(); 280 items = items - (nwords/width); 281 282 #if GIET_DEBUG_MWMR 283 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n", 284 x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts ); 285 #endif 286 287 lock_release( &mwmr->lock ); 288 } 289 290 // we could deschedule before retry... 291 // giet_context_switch(); 245 292 } 246 293 } // end mwmr_write() … … 250 297 void mwmr_read( mwmr_channel_t * mwmr, 251 298 unsigned int * buffer, 252 unsigned int nitems) 253 { 254 unsigned int x; 299 unsigned int items) 300 { 301 302 #if GIET_DEBUG_MWMR 303 unsigned int x; 304 unsigned int y; 305 unsigned int lpid; 306 giet_proc_xyp( &x, &y, &lpid ); 307 #endif 308 309 unsigned int n; 255 310 unsigned int nwords; // requested transfer length (in words) 256 311 unsigned int depth; // channel depth (in words) … … 259 314 unsigned int ptr; // channel ptr 260 315 261 if ( nitems == 0) return;316 if (items == 0) return; 262 317 263 318 while (1) 264 319 { 265 320 // get the lock 266 mwmr_lock_acquire(&mwmr->lock);321 lock_acquire( &mwmr->lock ); 267 322 268 323 // compute nwords 269 depth = mwmr->depth;270 width = mwmr->width;271 sts = mwmr->sts;272 ptr = mwmr->ptr;273 nwords = width * nitems;324 depth = mwmr->depth; 325 width = mwmr->width; 326 sts = mwmr->sts; 327 ptr = mwmr->ptr; 328 nwords = width * items; 274 329 275 330 if (sts >= nwords) // read nwords, release lock and return 276 331 { 277 for ( x = 0; x < nwords; x++)332 for (n = 0; n < nwords; n++) 278 333 { 279 buffer[ x] = mwmr->data[ptr];334 buffer[n] = mwmr->data[ptr]; 280 335 if ((ptr + 1) == depth) ptr = 0; 281 336 else ptr = ptr + 1; … … 283 338 mwmr->sts = mwmr->sts - nwords; 284 339 mwmr->ptr = ptr; 285 mwmr->lock = 0; 340 341 #if GIET_DEBUG_MWMR 342 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n", 343 x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts ); 344 #endif 345 346 lock_release( &mwmr->lock ); 286 347 return; 287 348 } 288 else if (sts < width) // release lock and deschedule289 { 290 mwmr->lock = 0;291 } 292 else // read as many items as possible, release lock and deschedule349 else if (sts < width) // release lock and retry 350 { 351 lock_release( &mwmr->lock ); 352 } 353 else // read as many items as possible, release lock and retry 293 354 { 294 355 nwords = (sts / width) * width; // integer number of items 295 for ( x = 0; x < nwords; x++)356 for (n = 0; n < nwords; n++) 296 357 { 297 buffer[ x] = mwmr->data[ptr];358 buffer[n] = mwmr->data[ptr]; 298 359 if ((ptr + 1) == depth) ptr = 0; 299 360 else ptr = ptr + 1; … … 302 363 mwmr->ptr = ptr; 303 364 buffer = buffer + nwords; 304 nitems = nitems - (nwords/width); 305 mwmr->lock = 0; 306 } 307 giet_context_switch(); 365 items = items - (nwords/width); 366 367 #if GIET_DEBUG_MWMR 368 giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n", 369 x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts ); 370 #endif 371 372 lock_release( &mwmr->lock ); 373 } 374 375 // we could deschedule before retry... 376 // giet_context_switch(); 308 377 } 309 378 } // end mwmr_read()
Note: See TracChangeset
for help on using the changeset viewer.