/* CIVL model of dotProduct_critical.c. To verify: * civl verify dotProduct_critical.cvl */ #include #include #include #define N 10 #define THREAD_MAX 4 /* Does thread t own iteration i in loop with n iterations? */ #define CIVL_owns(t, n, i) ((i)%(n)==(t)) _Bool critical_lock = $false; int main (int argc, char *argv[]) { double a[N], b[N]; double sum = 0.0; int nthreads; // translation of parallel construct // #pragma omp parallel shared(a,b,sum) private(i, localsum) // note: tid should be private. corrected here. { int barrier = 0; void thread(int _tid, int _nthreads) { int i, tid; double localsum; tid = _tid; if (_tid == 0) { nthreads =_nthreads; printf("Number of threads = %d\n", nthreads); } for (i=0; i < N; i++) { if (CIVL_owns(_tid, _nthreads, i)) { a[i] = b[i] = (double)i; } } barrier++; $when (barrier==_nthreads); localsum = 0; for (i=0; i < N; i++) { if (CIVL_owns(_tid, _nthreads, i)) { localsum = localsum + (a[i] * b[i]); } } $when (!critical_lock) critical_lock = $true; sum = sum + localsum; critical_lock = $false; } int _nthreads = 1+$choose_int(THREAD_MAX); $proc threads[_nthreads]; for (int i=0; i<_nthreads; i++) threads[i] = $spawn thread(i, _nthreads); for (int i=0; i<_nthreads; i++) $wait(threads[i]); } printf(" Sum = %2.1f\n",sum); }