diff --git a/micro-benchmarks/DRB027-taskdependmissing-orig-yes.c b/micro-benchmarks/DRB027-taskdependmissing-orig-yes.c index 44b30a5..7373750 100644 --- a/micro-benchmarks/DRB027-taskdependmissing-orig-yes.c +++ b/micro-benchmarks/DRB027-taskdependmissing-orig-yes.c @@ -47,20 +47,30 @@ THE POSSIBILITY OF SUCH DAMAGE. /* Two tasks without depend clause to protect data writes. i is shared for two tasks based on implicit data-sharing attribute rules. -Data race pair: i@61:5:W vs. i@63:5:W +Data race pair: i@63:5:W vs. i@67:5:W */ #include #include +#include "signaling.h" + int main() { - int i=0; -#pragma omp parallel + int i=0, sem=0; +#pragma omp parallel shared(sem) num_threads(2) #pragma omp single { #pragma omp task - i = 1; + { + i = 1; + SIGNAL(sem); + WAIT(sem,2); + } #pragma omp task + { i = 2; + SIGNAL(sem); + WAIT(sem,2); + } } printf ("i=%d\n",i); diff --git a/micro-benchmarks/DRB027b-taskdependmissing-orig-yes.c b/micro-benchmarks/DRB027b-taskdependmissing-orig-yes.c new file mode 100644 index 0000000..1187cd1 --- /dev/null +++ b/micro-benchmarks/DRB027b-taskdependmissing-orig-yes.c @@ -0,0 +1,79 @@ +/* +Copyright (c) 2017, Lawrence Livermore National Security, LLC. +Produced at the Lawrence Livermore National Laboratory +Written by Chunhua Liao, Pei-Hung Lin, Joshua Asplund, +Markus Schordan, and Ian Karlin +(email: liao6@llnl.gov, lin32@llnl.gov, asplund1@llnl.gov, +schordan1@llnl.gov, karlin1@llnl.gov) +LLNL-CODE-732144 +All rights reserved. + +This file is part of DataRaceBench. For details, see +https://github.com/LLNL/dataracebench. Please also see the LICENSE file +for our additional BSD notice. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the disclaimer below. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the disclaimer (as noted below) + in the documentation and/or other materials provided with the + distribution. + +* Neither the name of the LLNS/LLNL nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL +SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +Two tasks without depend clause to protect data writes. +i is shared for two tasks based on implicit data-sharing attribute rules. +Data race pair: i@63:5:W vs. i@67:5:W +*/ +#include +#include +#include "signaling.h" + +int main() +{ + int i=0, sem=0; +#pragma omp parallel shared(sem) num_threads(2) +{ +#pragma omp masked + { +#pragma omp task + { + SIGNAL(sem); + i = 1; + } +#pragma omp task + { + SIGNAL(sem); + i = 2; + } + #pragma omp taskwait + } + WAIT(sem, 2); +} + printf ("i=%d\n",i); + return 0; +} diff --git a/micro-benchmarks/DRB131-taskdep4-orig-omp45-yes.c b/micro-benchmarks/DRB131-taskdep4-orig-omp45-yes.c index 45940a9..4877917 100644 --- a/micro-benchmarks/DRB131-taskdep4-orig-omp45-yes.c +++ b/micro-benchmarks/DRB131-taskdep4-orig-omp45-yes.c @@ -11,22 +11,30 @@ * There is no completion restraint on the second child task. Hence, immediately after the first * taskwait it is unsafe to access the y variable since the second child task may still be * executing. - * Data Race at y@28:2:W vs. y@34:19:R + * Data Race at y@34:4:W vs. y@42:19:R */ #include #include +#include "signaling.h" void foo(){ - int x = 0, y = 2; + int x = 0, y = 2, sem = 0; - #pragma omp task depend(inout: x) shared(x) - x++; //1st Child Task + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; //1st Child Task + } - #pragma omp task shared(y) - y--; // 2nd child task + #pragma omp task shared(y, sem) + { + SIGNAL(sem); + y--; // 2nd child task + } + WAIT(sem, 2); #pragma omp task depend(in: x) if(0) // 1st taskwait {} @@ -37,7 +45,7 @@ void foo(){ int main(){ - #pragma omp parallel + #pragma omp parallel num_threads(2) #pragma omp single foo(); diff --git a/micro-benchmarks/DRB131b-taskdep4-orig-omp45-yes.c b/micro-benchmarks/DRB131b-taskdep4-orig-omp45-yes.c new file mode 100644 index 0000000..49e05b5 --- /dev/null +++ b/micro-benchmarks/DRB131b-taskdep4-orig-omp45-yes.c @@ -0,0 +1,57 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + +/* + * There is no completion restraint on the second child task. Hence, immediately after the first + * taskwait it is unsafe to access the y variable since the second child task may still be + * executing. + * Data Race at y@36:4:W vs. y@43:19:R +*/ + +#include +#include +#include "signaling.h" + +int sem = 0; + +void foo(){ + + int x = 0, y = 2; + + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; //1st Child Task + } + + #pragma omp task shared(y, sem) + { + SIGNAL(sem); + y--; // 2nd child task + } + + #pragma omp task depend(in: x) if(0) // 1st taskwait + {} + + printf("x=%d\n",x); + printf("y=%d\n",y); + #pragma omp taskwait // 2nd taskwait +} + + +int main(){ + #pragma omp parallel + { + #pragma omp masked + foo(); + WAIT(sem, 2); + } + + return 0; +} diff --git a/micro-benchmarks/DRB132-taskdep4-orig-omp45-no.c b/micro-benchmarks/DRB132-taskdep4-orig-omp45-no.c index 78bad68..1406b01 100644 --- a/micro-benchmarks/DRB132-taskdep4-orig-omp45-no.c +++ b/micro-benchmarks/DRB132-taskdep4-orig-omp45-no.c @@ -14,17 +14,25 @@ #include #include +#include "signaling.h" void foo(){ - int x = 0, y = 2; + int x = 0, y = 2, sem = 0; - #pragma omp task depend(inout: x) shared(x) - x++; //1st Child Task + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; //1st Child Task + } - #pragma omp task shared(y) - y--; // 2nd child task + #pragma omp task shared(y, sem) + { + SIGNAL(sem); + y--; // 2nd child task + } + WAIT(sem, 2); #pragma omp task depend(in: x) if(0) // 1st taskwait {} @@ -37,7 +45,7 @@ void foo(){ int main(){ - #pragma omp parallel + #pragma omp parallel num_threads(2) #pragma omp single foo(); diff --git a/micro-benchmarks/DRB132b-taskdep4-orig-omp45-no.c b/micro-benchmarks/DRB132b-taskdep4-orig-omp45-no.c new file mode 100644 index 0000000..91d185d --- /dev/null +++ b/micro-benchmarks/DRB132b-taskdep4-orig-omp45-no.c @@ -0,0 +1,58 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + +/* The second taskwait ensures that the second child task has completed; hence it is safe to access + * the y variable in the following print statement. + * */ + + +#include +#include +#include "signaling.h" + +int sem = 0; + +void foo(){ + + int x = 0, y = 2; + + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; //1st Child Task + } + + #pragma omp task shared(y, sem) + { + SIGNAL(sem); + y--; // 2nd child task + } + + #pragma omp task depend(in: x) if(0) // 1st taskwait + {} + + printf("x=%d\n",x); + + #pragma omp taskwait // 2nd taskwait + + printf("y=%d\n",y); +} + + +int main(){ + #pragma omp parallel + { + #pragma omp masked + foo(); + WAIT(sem, 2); + } + + return 0; +} + diff --git a/micro-benchmarks/DRB133-taskdep5-orig-omp45-no.c b/micro-benchmarks/DRB133-taskdep5-orig-omp45-no.c index c096fd3..4d133d5 100644 --- a/micro-benchmarks/DRB133-taskdep5-orig-omp45-no.c +++ b/micro-benchmarks/DRB133-taskdep5-orig-omp45-no.c @@ -17,16 +17,26 @@ #include #include +#include "signaling.h" + +int sem=0; void foo(){ int x = 0, y = 2; - #pragma omp task depend(inout: x) shared(x) + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); x++; // 1st child task + } - #pragma omp task depend(in: x) depend(inout: y) shared(x, y) - y = y-x; //2nd child task + #pragma omp task depend(in: x) depend(inout: y) shared(x, y, sem) + { + SIGNAL(sem); + y -= x; //2nd child task + } + WAIT(sem, 2); #pragma omp task depend(in: x) if(0) // 1st taskwait {} @@ -38,7 +48,7 @@ void foo(){ } int main(){ - #pragma omp parallel + #pragma omp parallel num_threads(2) #pragma omp single foo(); diff --git a/micro-benchmarks/DRB133b-taskdep5-orig-omp45-no.c b/micro-benchmarks/DRB133b-taskdep5-orig-omp45-no.c new file mode 100644 index 0000000..448b5c5 --- /dev/null +++ b/micro-benchmarks/DRB133b-taskdep5-orig-omp45-no.c @@ -0,0 +1,61 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + +/* The first two tasks are serialized, because a dependence on the first child is produced + * by x with the in dependence type in the depend clause of the second task. Generating task + * at the first taskwait only waits for the first child task to complete. The second taskwait + * guarantees completion of the second task before y is accessed. Therefore there is no race + * condition. + * */ + + +#include +#include +#include "signaling.h" + +int sem=0; + +void foo(){ + int x = 0, y = 2; + + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; // 1st child task + } + + #pragma omp task depend(in: x) depend(inout: y) shared(x, y, sem) + { + SIGNAL(sem); + y -= x; //2nd child task + } + + #pragma omp task depend(in: x) if(0) // 1st taskwait + {} + + printf("x=%d\n",x); + + #pragma omp taskwait // 2nd taskwait + + printf("y=%d\n",y); +} + +int main(){ + #pragma omp parallel num_threads(2) + { + #pragma omp masked + { + foo(); + } + WAIT(sem, 2); + } + + return 0; +} + diff --git a/micro-benchmarks/DRB134-taskdep5-orig-omp45-yes.c b/micro-benchmarks/DRB134-taskdep5-orig-omp45-yes.c index df59a0b..eaca0fd 100644 --- a/micro-benchmarks/DRB134-taskdep5-orig-omp45-yes.c +++ b/micro-benchmarks/DRB134-taskdep5-orig-omp45-yes.c @@ -11,22 +11,32 @@ * by x with the in dependence type in the depend clause of the second task. Generating task * at the first taskwait only waits for the first child task to complete. The second taskwait * guarantees completion of the second task before y is accessed. If we access y before the - * second taskwait, there is a race condition at line 28:2 and 34:18. Data Race Pair, y@28:2:W vs. y@34:19:R + * second taskwait, there is a race condition at line 28:2 and 34:18. Data Race Pair, y@36:5:W vs. y@43:19:R * */ #include #include +#include "signaling.h" + +int sem=0; void foo(){ int x = 0, y = 2; - #pragma omp task depend(inout: x) shared(x) + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); x++; // 1st child task + } - #pragma omp task depend(in: x) depend(inout: y) shared(x, y) + #pragma omp task depend(in: x) depend(inout: y) shared(x, y, sem) + { + SIGNAL(sem); y -= x; //2nd child task + } + WAIT(sem, 2); #pragma omp task depend(in: x) if(0) // 1st taskwait {} @@ -38,7 +48,7 @@ void foo(){ } int main(){ - #pragma omp parallel + #pragma omp parallel num_threads(2) #pragma omp single foo(); diff --git a/micro-benchmarks/DRB134b-taskdep5-orig-omp45-yes.c b/micro-benchmarks/DRB134b-taskdep5-orig-omp45-yes.c new file mode 100644 index 0000000..7588363 --- /dev/null +++ b/micro-benchmarks/DRB134b-taskdep5-orig-omp45-yes.c @@ -0,0 +1,61 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + +/* The first two tasks are serialized, because a dependence on the first child is produced + * by x with the in dependence type in the depend clause of the second task. Generating task + * at the first taskwait only waits for the first child task to complete. The second taskwait + * guarantees completion of the second task before y is accessed. If we access y before the + * second taskwait, there is a race condition at line 36 ann 44. Data Race Pair, y@36:5:W vs. y@44:19:R + * */ + + +#include +#include +#include "signaling.h" + +int sem=0; + +void foo(){ + int x = 0, y = 2; + + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; // 1st child task + } + + #pragma omp task depend(in: x) depend(inout: y) shared(x, y, sem) + { + SIGNAL(sem); + y -= x; //2nd child task + } + + #pragma omp task depend(in: x) if(0) // 1st taskwait + {} + + printf("x=%d\n",x); + printf("y=%d\n",y); + + #pragma omp taskwait // 2nd taskwait + +} + +int main(){ + #pragma omp parallel num_threads(2) + { + #pragma omp masked + { + foo(); + } + WAIT(sem, 2); + } + + return 0; +} + diff --git a/micro-benchmarks/DRB136-taskdep-mutexinoutset-orig-yes.c b/micro-benchmarks/DRB136-taskdep-mutexinoutset-orig-yes.c index d073296..c19dba9 100644 --- a/micro-benchmarks/DRB136-taskdep-mutexinoutset-orig-yes.c +++ b/micro-benchmarks/DRB136-taskdep-mutexinoutset-orig-yes.c @@ -15,11 +15,12 @@ #include #include +#include "signaling.h" int main(){ - int a, b, c, d; + int a, b, c, d, sem = 0; - #pragma omp parallel + #pragma omp parallel num_threads(2) #pragma omp single { #pragma omp task depend(out: c) @@ -29,9 +30,17 @@ int main(){ #pragma omp task depend(out: b) b = 3; #pragma omp task depend(in: a) + { + SIGNAL(sem); + WAIT(sem,2); c += a; + } #pragma omp task depend(in: b) + { + SIGNAL(sem); + WAIT(sem,2); c += b; + } #pragma omp task depend(in: c) d = c; } diff --git a/micro-benchmarks/DRB136b-taskdep-mutexinoutset-orig-yes.c b/micro-benchmarks/DRB136b-taskdep-mutexinoutset-orig-yes.c new file mode 100644 index 0000000..58c0a21 --- /dev/null +++ b/micro-benchmarks/DRB136b-taskdep-mutexinoutset-orig-yes.c @@ -0,0 +1,67 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + + +/* Due to the missing mutexinoutset dependence type on c, these tasks will execute in any + * order leading to the data race at line 36. Data Race Pair, + c@35:7:W vs. c@35:7:W + c@35:7:W vs. c@39:11:R + c@37:7:W vs. c@39:11:R + * */ + + +#include +#include +#include "signaling.h" + +int main(){ + int a, b, c, d, sem = 0; + + #pragma omp parallel num_threads(2) + { + #pragma omp masked + { + #pragma omp task depend(out: c) + { + SIGNAL(sem); + c = 1; + } + #pragma omp task depend(out: a) + { + SIGNAL(sem); + a = 2; + } + #pragma omp task depend(out: b) + { + SIGNAL(sem); + b = 3; + } + #pragma omp task depend(in: a) + { + SIGNAL(sem); + c += a; + } + #pragma omp task depend(in: b) + { + SIGNAL(sem); + c += b; + } + #pragma omp task depend(in: c) + { + SIGNAL(sem); + d = c; + } + #pragma omp taskwait + } + WAIT(sem, 6); + } + + printf("%d\n",d); + return 0; +} diff --git a/micro-benchmarks/DRB165-taskdep4-orig-omp50-yes.c b/micro-benchmarks/DRB165-taskdep4-orig-omp50-yes.c index b78cd8d..bc9cd10 100644 --- a/micro-benchmarks/DRB165-taskdep4-orig-omp50-yes.c +++ b/micro-benchmarks/DRB165-taskdep4-orig-omp50-yes.c @@ -11,22 +11,30 @@ * There is no completion restraint on the second child task. Hence, immediately after the first * taskwait it is unsafe to access the y variable since the second child task may still be * executing. - * Data Race at y@28:2:W vs. y@33:19:R + * Data Race at y@34:4:W vs. y@41:19:R */ #include #include +#include "signaling.h" void foo(){ - int x = 0, y = 2; + int x = 0, y = 2, sem = 0; - #pragma omp task depend(inout: x) shared(x) - x++; //1st Child Task + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; //1st Child Task + } - #pragma omp task shared(y) - y--; // 2nd child task + #pragma omp task shared(y, sem) + { + SIGNAL(sem); + y--; // 2nd child task + } + WAIT(sem, 2); #pragma omp taskwait depend(in: x) // 1st taskwait printf("x=%d\n",x); @@ -36,7 +44,7 @@ void foo(){ int main(){ - #pragma omp parallel + #pragma omp parallel num_threads(2) #pragma omp single foo(); diff --git a/micro-benchmarks/DRB165b-taskdep4-orig-omp50-yes.c b/micro-benchmarks/DRB165b-taskdep4-orig-omp50-yes.c new file mode 100644 index 0000000..4abcdec --- /dev/null +++ b/micro-benchmarks/DRB165b-taskdep4-orig-omp50-yes.c @@ -0,0 +1,56 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + +/* + * There is no completion restraint on the second child task. Hence, immediately after the first + * taskwait it is unsafe to access the y variable since the second child task may still be + * executing. + * Data Race at y@36:4:W vs. y@42:19:R +*/ + +#include +#include +#include "signaling.h" + +int sem = 0; + +void foo(){ + + int x = 0, y = 2; + + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; //1st Child Task + } + + #pragma omp task shared(y, sem) + { + SIGNAL(sem); + y--; // 2nd child task + } + + #pragma omp taskwait depend(in: x) // 1st taskwait + + printf("x=%d\n",x); + printf("y=%d\n",y); + #pragma omp taskwait // 2nd taskwait +} + + +int main(){ + #pragma omp parallel + { + #pragma omp masked + foo(); + WAIT(sem, 2); + } + + return 0; +} diff --git a/micro-benchmarks/DRB168-taskdep5-orig-omp50-yes.c b/micro-benchmarks/DRB168-taskdep5-orig-omp50-yes.c index e8359f1..81060c6 100644 --- a/micro-benchmarks/DRB168-taskdep5-orig-omp50-yes.c +++ b/micro-benchmarks/DRB168-taskdep5-orig-omp50-yes.c @@ -11,33 +11,42 @@ * by x with the in dependence type in the depend clause of the second task. Generating task * at the first taskwait only waits for the first child task to complete. The second taskwait * guarantees completion of the second task before y is accessed. If we access y before the - * second taskwait, there is a race condition at line 28 ann 33. Data Race Pair, y@28:2:W vs. y@33:19:R + * second taskwait, there is a race condition at line 28 ann 33. Data Race Pair, y@36:5:W vs. y@43:19:R * */ #include #include +#include "signaling.h" + +int sem=0; void foo(){ int x = 0, y = 2; - #pragma omp task depend(inout: x) shared(x) - x++; // 1st child task + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; // 1st child task + } - #pragma omp task depend(in: x) depend(inout: y) shared(x, y) - y -= x; //2nd child task + #pragma omp task depend(in: x) depend(inout: y) shared(x, y, sem) + { + SIGNAL(sem); + y -= x; //2nd child task + } + WAIT(sem, 2); #pragma omp taskwait depend(in: x) // 1st taskwait printf("x=%d\n",x); printf("y=%d\n",y); - #pragma omp taskwait // 2nd taskwait } int main(){ - #pragma omp parallel + #pragma omp parallel num_threads(2) #pragma omp single foo(); diff --git a/micro-benchmarks/DRB168b-taskdep5-orig-omp50-yes.c b/micro-benchmarks/DRB168b-taskdep5-orig-omp50-yes.c new file mode 100644 index 0000000..5b939c6 --- /dev/null +++ b/micro-benchmarks/DRB168b-taskdep5-orig-omp50-yes.c @@ -0,0 +1,59 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + +/* The first two tasks are serialized, because a dependence on the first child is produced + * by x with the in dependence type in the depend clause of the second task. Generating task + * at the first taskwait only waits for the first child task to complete. The second taskwait + * guarantees completion of the second task before y is accessed. If we access y before the + * second taskwait, there is a race condition at line 36 ann 43. Data Race Pair, y@36:5:W vs. y@43:19:R + * */ + + +#include +#include +#include "signaling.h" + +int sem=0; + +void foo(){ + int x = 0, y = 2; + + #pragma omp task depend(inout: x) shared(x, sem) + { + SIGNAL(sem); + x++; // 1st child task + } + + #pragma omp task depend(in: x) depend(inout: y) shared(x, y, sem) + { + SIGNAL(sem); + y -= x; //2nd child task + } + + #pragma omp taskwait depend(in: x) // 1st taskwait + + printf("x=%d\n",x); + printf("y=%d\n",y); + #pragma omp taskwait // 2nd taskwait + +} + +int main(){ + #pragma omp parallel num_threads(2) + { + #pragma omp masked + { + foo(); + } + WAIT(sem, 2); + } + + return 0; +} + diff --git a/micro-benchmarks/DRB173-non-sibling-taskdep-yes.c b/micro-benchmarks/DRB173-non-sibling-taskdep-yes.c index b3e24ce..661fe87 100644 --- a/micro-benchmarks/DRB173-non-sibling-taskdep-yes.c +++ b/micro-benchmarks/DRB173-non-sibling-taskdep-yes.c @@ -17,24 +17,35 @@ for details. #include #include +#include "signaling.h" void foo() { - int a = 0; + int a = 0, sem = 0; -#pragma omp parallel +#pragma omp parallel num_threads(2) #pragma omp single { #pragma omp task depend(inout : a) shared(a) { #pragma omp task depend(inout : a) shared(a) - a++; + { + a++; + SIGNAL(sem); + WAIT(sem,2); + } } #pragma omp task depend(inout : a) shared(a) { #pragma omp task depend(inout : a) shared(a) - a++; + { + a++; + SIGNAL(sem); + WAIT(sem,2); + } } + // allow other thread to steal first task + WAIT(sem,1); } printf("a=%d\n", a); diff --git a/micro-benchmarks/DRB173b-non-sibling-taskdep-yes.c b/micro-benchmarks/DRB173b-non-sibling-taskdep-yes.c new file mode 100644 index 0000000..20d89c9 --- /dev/null +++ b/micro-benchmarks/DRB173b-non-sibling-taskdep-yes.c @@ -0,0 +1,53 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file +for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + +/* + * Data race between non-sibling tasks with declared task dependency + * Derived from code in https://hal.archives-ouvertes.fr/hal-02177469/document, + * Listing 1.1 + * Data Race Pair, a@30:7:W vs. a@36:7:W + * */ + +#include +#include +#include "signaling.h" + +void foo() { + int a = 0, sem = 0; + +#pragma omp parallel num_threads(2) +{ +#pragma omp masked +#pragma omp taskgroup + { +#pragma omp task depend(inout : a) shared(a) + { +#pragma omp task depend(inout : a) shared(a) + SIGNAL(sem); + a++; + } + +#pragma omp task depend(inout : a) shared(a) + { +#pragma omp task depend(inout : a) shared(a) + SIGNAL(sem); + a++; + } + } + WAIT(sem,2); +} + printf("a=%d\n", a); +} + +int main() { + foo(); + + return 0; +} diff --git a/micro-benchmarks/DRB175-non-sibling-taskdep2-yes.c b/micro-benchmarks/DRB175-non-sibling-taskdep2-yes.c index 5121111..e44ca1f 100644 --- a/micro-benchmarks/DRB175-non-sibling-taskdep2-yes.c +++ b/micro-benchmarks/DRB175-non-sibling-taskdep2-yes.c @@ -13,19 +13,25 @@ for details. * with declared task dependency * Derived from code in https://hal.archives-ouvertes.fr/hal-02177469/document, * Listing 1.3 - * Data Race Pair, a@28:6:W vs. a@28:6:W + * Schedule forced to execute all tasks by different threads. + * Data Race Pair, a@32:8:W vs. a@32:8:W * */ #include #include +#include "signaling.h" void foo() { - int a = 0; + int a = 0, sem = 0; #pragma omp parallel { #pragma omp task depend(inout : a) shared(a) - a++; + { + SIGNAL(sem); + WAIT(sem, omp_get_num_threads()); + a++; + } } printf("a=%d\n", a); } diff --git a/micro-benchmarks/DRB175b-non-sibling-taskdep2-yes.c b/micro-benchmarks/DRB175b-non-sibling-taskdep2-yes.c new file mode 100644 index 0000000..9c65c85 --- /dev/null +++ b/micro-benchmarks/DRB175b-non-sibling-taskdep2-yes.c @@ -0,0 +1,44 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file +for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + +/* + * Data race between non-sibling tasks created from different implicit tasks + * with declared task dependency + * Derived from code in https://hal.archives-ouvertes.fr/hal-02177469/document, + * Listing 1.3 + * Schedule encouraged to execute all tasks by thread 0. + * Data Race Pair, a@28:6:W vs. a@28:6:W + * */ + +#include +#include +#include "signaling.h" + +void foo() { + int a = 0, sem = 0; + +#pragma omp parallel + { +#pragma omp task depend(inout : a) shared(a) + { + SIGNAL(sem); + a++; + } + if (omp_get_thread_num() != 0) + WAIT(sem, omp_get_num_threads()); + } + printf("a=%d\n", a); +} + +int main() { + foo(); + + return 0; +} diff --git a/micro-benchmarks/DRB177-fib-taskdep-yes.c b/micro-benchmarks/DRB177-fib-taskdep-yes.c index e76a9aa..bc53827 100644 --- a/micro-benchmarks/DRB177-fib-taskdep-yes.c +++ b/micro-benchmarks/DRB177-fib-taskdep-yes.c @@ -22,13 +22,19 @@ int fib(int n) { if (n < 2) return n; #pragma omp task shared(i) depend(out : i) - i = fib(n - 1); + { + i = fib(n - 1); + } #pragma omp task shared(j) depend(out : j) - j = fib(n - 2); -#pragma omp task shared(i, j) depend(in : j) - s = i + j; + { + j = fib(n - 2); + } +#pragma omp task shared(i, j, s) depend(in : j) + { + s = i + j; + } #pragma omp taskwait - return i + j; + return s; } int main(int argc, char **argv) { diff --git a/micro-benchmarks/DRB177b-fib-taskdep-yes.c b/micro-benchmarks/DRB177b-fib-taskdep-yes.c new file mode 100644 index 0000000..b1211c4 --- /dev/null +++ b/micro-benchmarks/DRB177b-fib-taskdep-yes.c @@ -0,0 +1,57 @@ +/* +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! +!!! Copyright (c) 2017-20, Lawrence Livermore National Security, LLC +!!! and DataRaceBench project contributors. See the DataRaceBench/COPYRIGHT file +for details. +!!! +!!! SPDX-License-Identifier: (BSD-3-Clause) +!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! + */ + +/* + * Fibonacci code with data race (possible to scale problem size by providing + * size argument). + * Data Race Pair, i@25:5:W vs. i@29:7:R + * */ + +#include +#include +#include "signaling.h" + +int sem = 0; + +int fib(int n) { + int i, j, s; + if (n < 2) + return n; +#pragma omp task shared(i, sem) depend(out : i) + { + i = fib(n - 1); + } +#pragma omp task shared(j, sem) depend(out : j) + { + j = fib(n - 2); + } +#pragma omp task shared(i, j, s, sem) depend(in : j) + { + s = i + j; + } +#pragma omp taskwait + return s; +} + +int main(int argc, char **argv) { + int n = 10; + if (argc > 1) + n = atoi(argv[1]); +#pragma omp parallel + { +#pragma omp masked + { + printf("fib(%i) = %i\n", n, fib(n)); + SIGNAL(sem); + } + WAIT(sem, 1); + } + return 0; +}