Changeset 228 for soft/giet_vm/libs/barrier.c
- Timestamp:
- Feb 12, 2013, 6:33:31 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/libs/barrier.c
r165 r228 15 15 16 16 /////////////////////////////////////////////////////////////////////////////////// 17 // 17 // barrier_init() 18 18 // This function makes a cooperative initialisation of the barrier: 19 19 // several tasks try to initialize the barrier, but the initialisation 20 20 // is done by only one task, using LL/SC instructions. 21 21 /////////////////////////////////////////////////////////////////////////////////// 22 void barrier_init( giet_barrier_t* barrier, 23 unsigned int value ) 24 { 25 unsigned int* pinit = (unsigned int*)&barrier->init; 26 unsigned int* pcount = (unsigned int*)&barrier->count; 22 void barrier_init( giet_barrier_t * barrier, unsigned int value) { 23 unsigned int * pinit = (unsigned int *) &barrier->init; 24 unsigned int * pcount = (unsigned int *) &barrier->count; 27 25 28 26 // parallel initialisation using atomic instructions LL/SC … … 30 28 // no output 31 29 asm volatile ("_barrier_init_test: \n" 32 "ll $2, 0(%0) \n" /* read initial value */ 33 "bnez $2, _barrier_init_done \n" 34 "move $3, %2 \n" 35 "sc $3, 0(%0) \n" /* write initial value */ 36 "beqz $3, _barrier_init_test \n" 37 "move $3, %2 \n" 38 "sw $3, 0(%1) \n" /* write count */ 39 "_barrier_init_done: \n" 40 :: "r"(pinit), "r"(pcount), "r"(value) 41 : "$2", "$3"); 30 "ll $2, 0(%0) \n" /* read initial value */ 31 "bnez $2, _barrier_init_done \n" 32 "move $3, %2 \n" 33 "sc $3, 0(%0) \n" /* write initial value */ 34 "beqz $3, _barrier_init_test \n" 35 "move $3, %2 \n" 36 "sw $3, 0(%1) \n" /* write count */ 37 "_barrier_init_done: \n" 38 : 39 : "r"(pinit), "r"(pcount), "r"(value) 40 : "$2", "$3"); 42 41 } 42 43 43 44 /////////////////////////////////////////////////////////////////////////////////// 44 // 45 // barrier_wait() 45 46 // This blocking function uses LL/SC to decrement the barrier's counter. 46 47 // Then, it uses a busy_waiting mechanism if it is not the last. 47 48 // (because the GIET does not support dynamic task scheduling/descheduling) 48 49 /////////////////////////////////////////////////////////////////////////////////// 49 void barrier_wait( giet_barrier_t* barrier ) 50 { 51 unsigned int* pcount = (unsigned int*)&barrier->count; 50 void barrier_wait(giet_barrier_t * barrier) { 51 unsigned int * pcount = (unsigned int *) &barrier->count; 52 52 unsigned int maxcount = barrier->init; 53 53 unsigned int count; … … 57 57 // - output : counter value 58 58 asm volatile ("_barrier_decrement: \n" 59 60 61 62 63 64 65 59 "ll %0, 0(%1) \n" 60 "addi $3, %0, -1 \n" 61 "sc $3, 0(%1) \n" 62 "beqz $3, _barrier_decrement \n" 63 : "=&r"(count) 64 : "r"(pcount) 65 : "$2", "$3"); 66 66 67 67 // the last task re-initializes the barrier counter to the max value, 68 68 // waking up all other waiting tasks 69 69 70 if (count == 1) // last task71 {70 if (count == 1) { 71 // last task 72 72 *pcount = maxcount; 73 73 } 74 else // other tasks busy-wait75 {74 else { 75 // other tasks busy-wait 76 76 while (*pcount != maxcount) asm volatile ("nop"); 77 77 } 78 78 } 79 79 80 // Local Variables: 81 // tab-width: 4 82 // c-basic-offset: 4 83 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 84 // indent-tabs-mode: nil 85 // End: 86 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 87
Note: See TracChangeset
for help on using the changeset viewer.