source: CIVL/examples/cuda/exitBarrier.cvl@ c9cfd85

1.23 2.0 main test-branch
Last change on this file since c9cfd85 was 3ff27cf, checked in by Manchun Zheng <zmanchun@…>, 11 years ago

updated examples since $assert/$assume has been changed to functions; fixed the model builder for the new side-effect remover.

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

  • Property mode set to 100644
File size: 3.9 KB
RevLine 
[d0d1fc3]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// Commandline execution:
27// civl verify exitBarrier.cvl
28
29// TODO: Right now, the thread termination is simply
30// a "return" statement. Anyway for that to actually
31// kill the thread?
32
[e6b02c8]33#include <civlc.cvh>
34#include <concurrency.cvh>
[d0d1fc3]35
36struct _CIVL_Barrier {
37 int numProcs; //how many are enrolled to begin with, cannot change
38 int numWaiting; //New variable for exit barriers, how many you need to wait for, can change
39 int *in_barrier;
40 int num_in_barrier;
41 int lock;
42};
43
44typedef struct _CIVL_Barrier CIVL_Barrier;
45
46void CIVL_Barrier_init(int numProcs, CIVL_Barrier *barrier, int *array) {
47 barrier->numProcs = numProcs;
48 barrier->numWaiting = numProcs;
49 barrier->num_in_barrier = 0;
50 barrier->lock = 0;
51 barrier->in_barrier = array;
52 for (int i=0; i<numProcs; i++)
53 barrier->in_barrier[i] = 0;
54}
55
56void CIVL_barrier(CIVL_Barrier *barrier, int tid) {
57 $when (barrier->lock==0) barrier->lock = 1;
58 barrier->in_barrier[tid] = 1;
59 barrier->num_in_barrier++;
60
61 //simply wait for how many need to be waited for, but
62 //free them all. No exceptions.
63 if (barrier->num_in_barrier == barrier->numWaiting) {
64 for (int i=0; i<barrier->numProcs; i++)
65 barrier->in_barrier[i] = 0;
66 barrier->num_in_barrier = 0;
67 }
68 barrier->lock = 0;
69 $when (barrier->in_barrier[tid] == 0);
70}
71
72//The resign function: Basically the same, but
73//decrement the number waiting for. If
74//A barrier is waiting on the resigning thread, then free
75//the barrier before leaving. No need to wait also.
76void CIVL_barrier_resign(CIVL_Barrier *barrier, int tid) {
77 $when (barrier->lock==0) barrier->lock = 1;
78 barrier->in_barrier[tid] = 1;
79 barrier->numWaiting--;
80 if (barrier->num_in_barrier == barrier->numWaiting) {
81 for (int i=0; i<barrier->numProcs; i++)
82 barrier->in_barrier[i] = 0;
83 barrier->num_in_barrier = 0;
84 }
85 barrier->lock = 0;
86}
87
88#define CIVL_barrier_exit(barrier, tid) CIVL_barrier_resign(barrier, tid); return
89
90void main() {
91 int N=4;
92 $proc threads[N];
93 int counter = 0;
94 CIVL_Barrier b;
95 int barrier_array[N];
96
97 void run_proc0(int tid) {
[3ff27cf]98 $assert((counter == 0));
[d0d1fc3]99 CIVL_barrier_exit(&b, tid);
100 }
101
102 void run_proc1(int tid) {
[3ff27cf]103 $assert((counter == 0));
[d0d1fc3]104 CIVL_barrier(&b, tid);
105 counter++;
106 CIVL_barrier_exit(&b, tid);
107 }
108
109 void run_proc2(int tid) {
[3ff27cf]110 $assert((counter == 0));
[d0d1fc3]111 CIVL_barrier(&b, tid);
112 counter++;
113 CIVL_barrier(&b, tid);
[3ff27cf]114 $assert((counter == 3));
[d0d1fc3]115 CIVL_barrier_exit(&b, tid);
116 }
117
118 void run_proc3(int tid) {
[3ff27cf]119 $assert((counter == 0));
[d0d1fc3]120 CIVL_barrier(&b, tid);
121 counter++;
122 CIVL_barrier(&b, tid);
[3ff27cf]123 $assert((counter == 3));
[d0d1fc3]124 CIVL_barrier(&b, tid);
125 counter--;
126 CIVL_barrier_exit(&b, tid);
127 }
128
129 CIVL_Barrier_init(N, &b, barrier_array);
130
131 //Spawn threads
132 $proc proc0 = $spawn run_proc0(0);
133 $proc proc1 = $spawn run_proc1(1);
134 $proc proc2 = $spawn run_proc2(2);
135 $proc proc3 = $spawn run_proc3(3);
136
137 //wait for threads
138 $wait(proc0);
139 $wait(proc1);
140 $wait(proc2);
141 $wait(proc3);
142
[3ff27cf]143 $assert((counter == 2));
[d0d1fc3]144}
Note: See TracBrowser for help on using the repository browser.