source: CIVL/examples/cuda/exitBarrier.cvl@ 9705dfd

1.23 2.0 main test-branch
Last change on this file since 9705dfd was dd83b0d, checked in by Manchun Zheng <zmanchun@…>, 13 years ago

add Tyler's cvl program that models the exit barrier of Cuda.

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

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