#include "srl_barrier.h" /* int srl_barrier_init(srl_barrier_t barrier) { register int* pinit = (int*)&barrier->init_val; register int* pcount = (int*)&barrier->count; // parallel initialisation using atomic instructions LL/SC asm volatile ("_barrier_init_test: \n" "ll $2, 0(%0) \n" // read initial value "bnez $2, _barrier_init_done \n" "move $3, %2 \n" "sc $3, 0(%0) \n" // try to write initial value "beqz $3, _barrier_init_test \n" "move $3, %2 \n" "sw $3, 0(%1) \n" // write count "sync" "_barrier_init_done: \n" ::"r"(pinit),"r"(pcount),"r"(value):"$2","$3"); return 0 ; } */ void srl_barrier_wait( srl_barrier_t barrier) { register int* pcount = (int*)&barrier->count; register int maxcount = (int)barrier->init_val; register int count; // parallel decrement barrier counter using atomic instructions LL/SC // input : pointer on the barrier counter // output : counter value asm volatile ("_barrier_decrement: \n" "ll %0, 0(%1) \n" "addi $3, %0, -1 \n" "sc $3, 0(%1) \n" "beqz $3, _barrier_decrement \n" :"=r"(count):"r"(pcount):"$2","$3"); // the last task re-initializes the barrier counter // to the max value, waking up all other waiting tasks //TODO:check it out if ( count == 0 ) // last task { //*pcount = maxcount; asm volatile( "sw %0, (%1)\n" "sync \n" ::"r"(maxcount),"r"(pcount)); return ; } else // other tasks { // while ( *pcount != maxcount ) { } // busy waiting srl_sched_wait_eq(pcount, maxcount); // busy waiting return ; } }