| [4208097] | 1 | /* This file completes the definitions of types and some functions
|
|---|
| 2 | * for concurrency, which are declared in concurrency.cvh.
|
|---|
| 3 | */
|
|---|
| 4 |
|
|---|
| [bf584ca] | 5 | #ifndef __CIVLC_CONCURRENCY__
|
|---|
| [4208097] | 6 | #define __CIVLC_CONCURRENCY__
|
|---|
| [d98b14a] | 7 | #include<civlc.cvh>
|
|---|
| [4d9f19e] | 8 | #include<concurrency.cvh>
|
|---|
| [be4d6aa] | 9 | #include<seq.cvh>
|
|---|
| [e93c797] | 10 | #pragma CIVL ACSL
|
|---|
| [4208097] | 11 | /* *********************** Types *********************** */
|
|---|
| 12 |
|
|---|
| 13 | /* A data type representing a global barrier which must be operated by local
|
|---|
| 14 | * barriers. Completes the declaration of this type in civlc-common.h.
|
|---|
| 15 | */
|
|---|
| [5217420] | 16 | struct _gbarrier {
|
|---|
| [4208097] | 17 | int nprocs;
|
|---|
| 18 | $proc proc_map[]; // initialized as all $proc_null.
|
|---|
| 19 | _Bool in_barrier[]; // initialized as all false.
|
|---|
| 20 | int num_in_barrier; // initialized as 0.
|
|---|
| 21 | };
|
|---|
| 22 |
|
|---|
| 23 | /* A data type representing a global barrier which used for
|
|---|
| 24 | * operating global barriers. The local barrier type has
|
|---|
| 25 | * a handle of a global barrier.
|
|---|
| 26 | * Completes the declaration of this type in civlc-common.h.
|
|---|
| 27 | */
|
|---|
| [5217420] | 28 | struct _barrier {
|
|---|
| [4208097] | 29 | int place;
|
|---|
| 30 | $gbarrier gbarrier; // initialized as 0.
|
|---|
| 31 | };
|
|---|
| 32 |
|
|---|
| 33 | /* *********************** Functions *********************** */
|
|---|
| 34 |
|
|---|
| [8d90ddd] | 35 | /*@ depends_on \access(barrier);
|
|---|
| [a956d76] | 36 | @ executes_when \true;
|
|---|
| [f86ba12] | 37 | @ */
|
|---|
| [4724a68] | 38 | $atomic_f void $barrier_enter($barrier barrier, int nprocs, void foo(void)){
|
|---|
| [d98b14a] | 39 | $gbarrier gbarrier=barrier->gbarrier;
|
|---|
| 40 | int myplace=barrier->place;
|
|---|
| 41 |
|
|---|
| 42 | $assert(!gbarrier->in_barrier[myplace],
|
|---|
| 43 | "the barrier of has already been entered with the place %d",
|
|---|
| 44 | myplace);
|
|---|
| 45 | gbarrier->in_barrier[barrier->place]=$true;
|
|---|
| [4149b300] | 46 | if(gbarrier->nprocs < nprocs){
|
|---|
| 47 | nprocs = gbarrier->nprocs;
|
|---|
| 48 | }
|
|---|
| [d98b14a] | 49 | if(++gbarrier->num_in_barrier == nprocs){
|
|---|
| [4724a68] | 50 | foo();
|
|---|
| [4149b300] | 51 | for(int i=0; i<gbarrier->nprocs; i++)
|
|---|
| [d98b14a] | 52 | gbarrier->in_barrier[i]=$false;
|
|---|
| 53 | gbarrier->num_in_barrier=0;
|
|---|
| 54 | }
|
|---|
| 55 | }
|
|---|
| [4208097] | 56 |
|
|---|
| [a777dc1] | 57 | /*@ depends_on \access(barrier);
|
|---|
| 58 | @ executes_when \true;
|
|---|
| 59 | @ */
|
|---|
| 60 | $atomic_f void $barrier_enter_simple($barrier barrier) {
|
|---|
| 61 | $gbarrier gbarrier=barrier->gbarrier;
|
|---|
| 62 | int myplace=barrier->place, nprocs = gbarrier->nprocs;
|
|---|
| 63 |
|
|---|
| 64 | $assert(!gbarrier->in_barrier[myplace],
|
|---|
| 65 | "the barrier of has already been entered with the place %d",
|
|---|
| 66 | myplace);
|
|---|
| 67 | gbarrier->in_barrier[myplace] = $true;
|
|---|
| 68 | if (++gbarrier->num_in_barrier == nprocs) {
|
|---|
| 69 | for(int i=0; i<nprocs; i++)
|
|---|
| 70 | gbarrier->in_barrier[i] = $false;
|
|---|
| 71 | gbarrier->num_in_barrier = 0;
|
|---|
| 72 | }
|
|---|
| 73 | }
|
|---|
| 74 |
|
|---|
| [8d90ddd] | 75 | /*@ depends_on \access(barrier);
|
|---|
| [f86ba12] | 76 | @ */
|
|---|
| [a777dc1] | 77 | $atomic_f void $barrier_exit($barrier barrier) {
|
|---|
| [d98b14a] | 78 | $when(!barrier->gbarrier->in_barrier[barrier->place]);
|
|---|
| 79 | }
|
|---|
| [4208097] | 80 |
|
|---|
| [8907091f] | 81 | void $barrier_call($barrier barrier) {
|
|---|
| [a777dc1] | 82 | $barrier_enter_simple(barrier);
|
|---|
| 83 | $barrier_exit(barrier);
|
|---|
| [4149b300] | 84 | }
|
|---|
| 85 |
|
|---|
| [a777dc1] | 86 | void $barrier_call_yield($barrier barrier) {
|
|---|
| 87 | $barrier_enter_simple(barrier);
|
|---|
| 88 | $yield();
|
|---|
| 89 | $barrier_exit(barrier);
|
|---|
| 90 | }
|
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| [4149b300] | 93 | void $barrier_call_subset($barrier barrier, int nprocs){
|
|---|
| [4724a68] | 94 | void empty_func(){}
|
|---|
| 95 | $barrier_enter(barrier, nprocs, empty_func);
|
|---|
| [4208097] | 96 | $barrier_exit(barrier);
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| [4724a68] | 99 | void $barrier_call_execute($barrier barrier, void foo(void)){
|
|---|
| 100 | $barrier_enter(barrier, barrier->gbarrier->nprocs, foo);
|
|---|
| 101 | $barrier_exit(barrier);
|
|---|
| 102 | }
|
|---|
| [d0bf94f] | 103 |
|
|---|
| [6185d35] | 104 | $atomic_f $gbarrier $gbarrier_create($scope scope, int size){
|
|---|
| [5217420] | 105 | $gbarrier gbarrier = ($gbarrier)$malloc(scope, sizeof(struct _gbarrier));
|
|---|
| [6185d35] | 106 |
|
|---|
| 107 | gbarrier->nprocs=size;
|
|---|
| 108 | gbarrier->proc_map=($proc[size])$lambda(int i) $proc_null;
|
|---|
| 109 | gbarrier->in_barrier=(_Bool[size])$lambda(int i) $false;
|
|---|
| 110 | gbarrier->num_in_barrier=0;
|
|---|
| 111 | return gbarrier;
|
|---|
| 112 | }
|
|---|
| 113 |
|
|---|
| 114 | $atomic_f void $gbarrier_destroy($gbarrier gbarrier){
|
|---|
| 115 | $free(gbarrier);
|
|---|
| 116 | }
|
|---|
| 117 |
|
|---|
| [4149b300] | 118 | int $get_nprocs($gbarrier gbarrier){
|
|---|
| 119 | return gbarrier->nprocs;
|
|---|
| 120 | }
|
|---|
| 121 |
|
|---|
| [6185d35] | 122 | $atomic_f $barrier $barrier_create($scope scope, $gbarrier gbarrier, int place){
|
|---|
| [a777dc1] | 123 | $assert(gbarrier->proc_map[place]==$proc_null,
|
|---|
| 124 | "the place %d in the global barrier has already been taken.", place);
|
|---|
| [6185d35] | 125 |
|
|---|
| [5217420] | 126 | $barrier barrier=($barrier)$malloc(scope, sizeof(struct _barrier));
|
|---|
| [6185d35] | 127 |
|
|---|
| 128 | barrier->place=place;
|
|---|
| 129 | barrier->gbarrier=gbarrier;
|
|---|
| 130 | gbarrier->proc_map[place]=$self;
|
|---|
| 131 | return barrier;
|
|---|
| 132 | }
|
|---|
| 133 |
|
|---|
| [a777dc1] | 134 | $atomic_f void $barrier_destroy($barrier barrier) {
|
|---|
| [6185d35] | 135 | $free(barrier);
|
|---|
| 136 | }
|
|---|
| 137 |
|
|---|
| [4208097] | 138 | #endif
|
|---|