[160] | 1 | #include "srl_barrier.h" |
---|
| 2 | /* |
---|
| 3 | int srl_barrier_init(srl_barrier_t barrier) |
---|
| 4 | { |
---|
| 5 | |
---|
| 6 | register int* pinit = (int*)&barrier->init_val; |
---|
| 7 | register int* pcount = (int*)&barrier->count; |
---|
| 8 | |
---|
| 9 | // parallel initialisation using atomic instructions LL/SC |
---|
| 10 | asm volatile ("_barrier_init_test: \n" |
---|
| 11 | "ll $2, 0(%0) \n" // read initial value |
---|
| 12 | "bnez $2, _barrier_init_done \n" |
---|
| 13 | "move $3, %2 \n" |
---|
| 14 | "sc $3, 0(%0) \n" // try to write initial value |
---|
| 15 | "beqz $3, _barrier_init_test \n" |
---|
| 16 | "move $3, %2 \n" |
---|
| 17 | "sw $3, 0(%1) \n" // write count |
---|
| 18 | "sync" |
---|
| 19 | "_barrier_init_done: \n" |
---|
| 20 | ::"r"(pinit),"r"(pcount),"r"(value):"$2","$3"); |
---|
| 21 | return 0 ; |
---|
| 22 | } |
---|
| 23 | */ |
---|
| 24 | |
---|
| 25 | void srl_barrier_wait( srl_barrier_t barrier) |
---|
| 26 | { |
---|
| 27 | register int* pcount = (int*)&barrier->count; |
---|
| 28 | register int maxcount = (int)barrier->init_val; |
---|
| 29 | register int count; |
---|
| 30 | |
---|
| 31 | // parallel decrement barrier counter using atomic instructions LL/SC |
---|
| 32 | // input : pointer on the barrier counter |
---|
| 33 | // output : counter value |
---|
| 34 | asm volatile ("_barrier_decrement: \n" |
---|
| 35 | "ll %0, 0(%1) \n" |
---|
| 36 | "addi $3, %0, -1 \n" |
---|
| 37 | "sc $3, 0(%1) \n" |
---|
| 38 | "beqz $3, _barrier_decrement \n" |
---|
| 39 | :"=r"(count):"r"(pcount):"$2","$3"); |
---|
| 40 | |
---|
| 41 | // the last task re-initializes the barrier counter |
---|
| 42 | // to the max value, waking up all other waiting tasks |
---|
| 43 | |
---|
| 44 | //TODO:check it out |
---|
| 45 | if ( count == 0 ) // last task |
---|
| 46 | { |
---|
| 47 | //*pcount = maxcount; |
---|
| 48 | asm volatile( "sw %0, (%1)\n" |
---|
| 49 | "sync \n" |
---|
| 50 | ::"r"(maxcount),"r"(pcount)); |
---|
| 51 | return ; |
---|
| 52 | } |
---|
| 53 | else // other tasks |
---|
| 54 | { |
---|
| 55 | // while ( *pcount != maxcount ) { } // busy waiting |
---|
| 56 | srl_sched_wait_eq(pcount, maxcount); // busy waiting |
---|
| 57 | return ; |
---|
| 58 | } |
---|
| 59 | |
---|
| 60 | } |
---|