Changeset 490 for soft/giet_vm/giet_common
- Timestamp:
- Jan 16, 2015, 1:24:18 PM (10 years ago)
- Location:
- soft/giet_vm/giet_common
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_common/utils.c
r466 r490 409 409 } 410 410 411 411 /////////////////////////////////////////////////////////////////////////////////// 412 // barrier functions 413 /////////////////////////////////////////////////////////////////////////////////// 414 void _barrier_init( _giet_barrier_t* barrier, 415 unsigned int ntasks ) 416 { 417 barrier->ntasks = ntasks; 418 barrier->count = ntasks; 419 barrier->sense = 0; 420 421 asm volatile ("sync" ::: "memory"); 422 } 423 424 //////////////////////////////////////////// 425 void _barrier_wait( _giet_barrier_t* barrier ) 426 { 427 428 // compute expected sense value 429 unsigned int expected; 430 if ( barrier->sense == 0 ) expected = 1; 431 else expected = 0; 432 433 // parallel decrement barrier counter using atomic instructions LL/SC 434 // - input : pointer on the barrier counter (pcount) 435 // - output : counter value (count) 436 volatile unsigned int* pcount = (unsigned int *)&barrier->count; 437 volatile unsigned int count = 0; // avoid a warning 438 439 asm volatile( "addu $2, %1, $0 \n" 440 "barrier_llsc: \n" 441 "ll $8, 0($2) \n" 442 "addi $9, $8, -1 \n" 443 "sc $9, 0($2) \n" 444 "beqz $9, barrier_llsc \n" 445 "addu %0, $8, $0 \n" 446 : "=r" (count) 447 : "r" (pcount) 448 : "$2", "$8", "$9", "memory" ); 449 450 // the last task re-initializes count and toggle sense, 451 // waking up all other waiting tasks 452 if (count == 1) // last task 453 { 454 barrier->count = barrier->ntasks; 455 barrier->sense = expected; 456 } 457 else // other tasks busy waiting the sense flag 458 { 459 // polling sense flag 460 // input: pointer on the sens flag (psense) 461 // input: expected sense value (expected) 462 volatile unsigned int* psense = (unsigned int *)&barrier->sense; 463 asm volatile ( "barrier_sense: \n" 464 "lw $3, 0(%0) \n" 465 "bne $3, %1, barrier_sense \n" 466 : 467 : "r"(psense), "r"(expected) 468 : "$3" ); 469 } 470 471 asm volatile ("sync" ::: "memory"); 472 } 473 474 /////////////////////////////////////////////////////////////////////////////////// 475 // Locks access functions 476 /////////////////////////////////////////////////////////////////////////////////// 477 478 /////////////////////////////////// 479 void _get_lock( _giet_lock_t* lock ) 480 { 481 register unsigned int* plock = &(lock->value); 482 483 #if NO_HARD_CC 484 485 register unsigned int delay = (_get_proctime() ^ _get_procid() << 4) & 0xFF; 486 if (delay == 0) delay = 0x80; 487 488 asm volatile ( 489 "_lock_llsc: \n" 490 " ll $2, 0(%0) \n" /* $2 <= lock current value */ 491 " bnez $2, _lock_delay \n" /* delay if lock already taken */ 492 " li $3, 1 \n" /* $3 <= argument for sc */ 493 " sc $3, 0(%0) \n" /* try to set lock */ 494 " bnez $3, _lock_ok \n" /* exit if atomic */ 495 " _lock_delay: \n" 496 " move $4, %1 \n" /* $4 <= delay */ 497 " _lock_loop: \n" 498 " addi $4, $4, -1 \n" /* $4 <= $4 - 1 */ 499 " bnez $4, _lock_loop \n" /* test end delay */ 500 " nop \n" 501 " j _lock_llsc \n" /* retry */ 502 " nop \n" 503 " _lock_ok: \n" 504 : 505 :"r"(plock), "r"(delay) 506 :"$2", "$3", "$4", "memory"); 507 #else 508 509 asm volatile ( 510 "_lock_llsc: \n" 511 " lw $2, 0(%0) \n" /* $2 <= lock current value */ 512 " bnez $2, _lock_llsc \n" /* retry if lock already taken */ 513 " nop \n" 514 " ll $2, 0(%0) \n" /* ll_buffer <= lock current value */ 515 " bnez $2, _lock_llsc \n" /* retry if lock already taken */ 516 " li $3, 1 \n" /* $3 <= argument for sc */ 517 " sc $3, 0(%0) \n" /* try to set lock */ 518 " beqz $3, _lock_llsc \n" /* retry if sc failure */ 519 " nop \n" 520 : 521 :"r"(plock) 522 :"$2", "$3", "memory"); 523 #endif 524 525 } 526 527 /////////////////////////////////////// 528 void _release_lock( _giet_lock_t* lock ) 529 { 530 asm volatile ( "sync\n" ::: "memory" ); 531 // sync is necessary because of the TSAR consistency model 532 lock->value = 0; 533 } 412 534 413 535 //////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_common/utils.h
r455 r490 35 35 extern _ld_symbol_t kernel_init_vbase; 36 36 37 38 39 /////////////////////////////////////////////////////////////////////////////////// 40 // Locks access functions 41 /////////////////////////////////////////////////////////////////////////////////// 42 volatile typedef struct _giet_barrier_s 43 { 44 char name[32]; // barrier name 45 unsigned int sense; // barrier state (toggle) 46 unsigned int ntasks; // total number of expected tasks 47 unsigned int count; // number of not arrived tasks 48 } _giet_barrier_t; 49 50 extern void _barrier_init( _giet_barrier_t* barrier, 51 unsigned int ntasks ); 52 53 extern void _barrier_wait( _giet_barrier_t* barrier ); 54 55 56 /////////////////////////////////////////////////////////////////////////////////// 57 // Locks access functions 58 /////////////////////////////////////////////////////////////////////////////////// 59 volatile typedef struct _giet_lock_s { unsigned int value; 60 unsigned int padding[15]; } _giet_lock_t; 61 62 63 extern void _get_lock(_giet_lock_t* lock); 64 65 extern void _release_lock(_giet_lock_t* lock); 37 66 /////////////////////////////////////////////////////////////////////////////////// 38 67 // CP0 registers access functions
Note: See TracChangeset
for help on using the changeset viewer.