Changeset 295 for soft/giet_vm/giet_libs/barrier.c
- Timestamp:
- Mar 26, 2014, 6:44:44 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_libs/barrier.c
r258 r295 15 15 16 16 /////////////////////////////////////////////////////////////////////////////////// 17 // barrier_init() 18 // This function makes a cooperative initialisation of the barrier: 19 // several tasks try to initialize the barrier, but the initialisation 20 // is done by only one task, using LL/SC instructions. 17 // This function initializes the barrier: this should be done by a single task. 21 18 /////////////////////////////////////////////////////////////////////////////////// 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; 25 26 // parallel initialisation using atomic instructions LL/SC 27 // inputs : pinit, pcount, value 28 // no output 29 asm volatile ("_barrier_init_test: \n" 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"); 19 void barrier_init( giet_barrier_t* barrier, 20 unsigned int value ) 21 { 22 barrier->init = value; 23 barrier->count = value; 41 24 } 42 25 43 26 44 27 /////////////////////////////////////////////////////////////////////////////////// 45 // barrier_wait()46 28 // This blocking function uses LL/SC to decrement the barrier's counter. 47 29 // Then, it uses a busy_waiting mechanism if it is not the last. 48 // (because the GIET does not support dynamic task scheduling/descheduling)49 30 /////////////////////////////////////////////////////////////////////////////////// 50 void barrier_wait(giet_barrier_t * barrier) { 31 void barrier_wait( giet_barrier_t* barrier ) 32 { 51 33 unsigned int * pcount = (unsigned int *) &barrier->count; 52 34 unsigned int maxcount = barrier->init; … … 56 38 // - input : pointer on the barrier counter 57 39 // - output : counter value 58 asm volatile ("_barrier_decrement: 40 asm volatile ("_barrier_decrement: \n" 59 41 "ll %0, 0(%1) \n" 60 42 "addi $3, %0, -1 \n" … … 68 50 // waking up all other waiting tasks 69 51 70 if (count == 1) { 52 if (count == 1) 53 { 71 54 // last task 72 55 *pcount = maxcount;
Note: See TracChangeset
for help on using the changeset viewer.