source: CIVL/examples/concurrency/exitBarrier.cvl

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 3.7 KB
RevLine 
[e548f734]1// Tyler Sorensen
2//
3// An attempt to create an "exit barrier"
4// as seen in NVIDIA PTX instructions
5// See "exit" and "bar.sync" instructions in PTX ISA
6//
7// The algorithm implemented uses the general CIVL barrier
8// module found in examples/concurrency/barrier2.cvl
9//
10// The exit semantics are a combination of barrier
11// resignation as seen in KRoC release of occam and
12// documented in the paper:
13// Higher Level of Process Synchronization by:
14// Peter H. Welch and David C. Wood.
15// and a return statement (to exit the thread)
16//
17// The resignation algorithm is given briefly in
18// the paper cited above which I attempted to
19// implement. However, this implementation assumes
20// that a resigned thread does not access the barrier
21// again! It is implemented with the exit barrier
22// semantics in mind, i.e. the thread will cease
23// execution right after resignation. No attempts
24// are made to guard against behavior deviating
25// from this.
26
27#include <civlc.cvh>
28#include <stdlib.h>
29
30struct _CIVL_Barrier {
31 int numProcs; //how many are enrolled to begin with, cannot change
32 int numWaiting; //New variable for exit barriers, how many you need to wait for, can change
33 int *in_barrier;
34 int num_in_barrier;
35 int lock;
36};
37
38typedef struct _CIVL_Barrier CIVL_Barrier;
39
40void CIVL_Barrier_init(int numProcs, CIVL_Barrier *barrier, int *array) {
41 barrier->numProcs = numProcs;
42 barrier->numWaiting = numProcs;
43 barrier->num_in_barrier = 0;
44 barrier->lock = 0;
45 barrier->in_barrier = array;
46 for (int i=0; i<numProcs; i++)
47 barrier->in_barrier[i] = 0;
48}
49
50void CIVL_barrier(CIVL_Barrier *barrier, int tid) {
51 $when (barrier->lock==0) barrier->lock = 1;
52 barrier->in_barrier[tid] = 1;
53 barrier->num_in_barrier++;
54
55 //simply wait for how many need to be waited for, but
56 //free them all. No exceptions.
57 if (barrier->num_in_barrier == barrier->numWaiting) {
58 for (int i=0; i<barrier->numProcs; i++)
59 barrier->in_barrier[i] = 0;
60 barrier->num_in_barrier = 0;
61 }
62 barrier->lock = 0;
63 $when (barrier->in_barrier[tid] == 0);
64}
65
66//The resign function: Basically the same, but
67//decrement the number waiting for. If
68//A barrier is waiting on the resigning thread, then free
69//the barrier before leaving. No need to wait also.
70void CIVL_barrier_resign(CIVL_Barrier *barrier, int tid) {
71 $when (barrier->lock==0) barrier->lock = 1;
72 barrier->in_barrier[tid] = 0; // was 1, changed to 0 by sfs
73 barrier->numWaiting--;
74 if (barrier->num_in_barrier == barrier->numWaiting) {
75 for (int i=0; i<barrier->numProcs; i++)
76 barrier->in_barrier[i] = 0;
77 barrier->num_in_barrier = 0;
78 }
79 barrier->lock = 0;
80}
81
82#define CIVL_barrier_exit(barrier, tid) CIVL_barrier_resign(barrier, tid); exit(0);
83
84void main() {
85 int N=4;
86 $proc threads[N];
87 int counter = 0;
88 CIVL_Barrier b;
89 int barrier_array[N];
90
91 void run_proc0(int tid) {
[3ff27cf]92 $assert((counter == 0));
[e548f734]93 CIVL_barrier_exit(&b, tid);
94 }
95
96 void run_proc1(int tid) {
[3ff27cf]97 $assert((counter == 0));
[e548f734]98 CIVL_barrier(&b, tid);
99 counter++;
100 CIVL_barrier_exit(&b, tid);
101 }
102
103 void run_proc2(int tid) {
[3ff27cf]104 $assert(counter == 0);
[e548f734]105 CIVL_barrier(&b, tid);
106 counter++;
107 CIVL_barrier(&b, tid);
[3ff27cf]108 $assert(counter == 3);
[e548f734]109 CIVL_barrier_exit(&b, tid);
110 }
111
112 void run_proc3(int tid) {
[3ff27cf]113 $assert(counter == 0);
[e548f734]114 CIVL_barrier(&b, tid);
115 counter++;
116 CIVL_barrier(&b, tid);
[3ff27cf]117 $assert(counter == 3);
[e548f734]118 CIVL_barrier(&b, tid);
119 counter--;
120 CIVL_barrier_exit(&b, tid);
121 }
122
123 CIVL_Barrier_init(N, &b, barrier_array);
124
125 //Spawn threads
126 $proc proc0 = $spawn run_proc0(0);
127 $proc proc1 = $spawn run_proc1(1);
128 $proc proc2 = $spawn run_proc2(2);
129 $proc proc3 = $spawn run_proc3(3);
130
131 //wait for threads
132 $wait(proc0);
133 $wait(proc1);
134 $wait(proc2);
135 $wait(proc3);
136
[3ff27cf]137 $assert(counter == 2);
[e548f734]138}
Note: See TracBrowser for help on using the repository browser.