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 | } |
---|