diff --git a/runtime/tests/vm/dart/tsan/array_data_race_test.dart b/runtime/tests/vm/dart/tsan/array_data_race_test.dart index a9cde1d2ebf..db24255c036 100644 --- a/runtime/tests/vm/dart/tsan/array_data_race_test.dart +++ b/runtime/tests/vm/dart/tsan/array_data_race_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// VMOptions=--experimental-shared-data +// VMOptions=--experimental-shared-data --no-osr --no-background-compilation import "dart:ffi"; import "dart:io"; @@ -15,29 +15,31 @@ import '../dylib_utils.dart'; @pragma("vm:shared") List? box; -@pragma("vm:never-inline") -noopt() {} - @pragma("vm:never-inline") dataRaceFromMain() { final localBox = box!; - for (var i = 0; i < 1000000; i++) { - localBox[0] += 1; - noopt(); + for (var i = 0; i < 50000; i++) { + usleep(100); + var t = localBox[0]; + usleep(100); + localBox[0] = t + 1; } } @pragma("vm:never-inline") dataRaceFromChild() { final localBox = box!; - for (var i = 0; i < 1000000; i++) { - localBox[0] += 1; - noopt(); + for (var i = 0; i < 50000; i++) { + usleep(100); + var t = localBox[0]; + usleep(100); + localBox[0] = t + 1; } } -child(_) { +child(replyPort) { dataRaceFromChild(); + replyPort.send(null); } final nativeLib = dlopenPlatformSpecific('ffi_test_functions'); @@ -53,6 +55,13 @@ final setFfiNativeResolverForTest = nativeLib @Native(symbol: 'UnsafeSetSharedTo') external int unsafeSetSharedTo(Object library_name, String name, Object value); +// Leaf: we don't want the two threads to synchronize via safepoint. +final usleep = DynamicLibrary.process() + .lookupFunction( + 'usleep', + isLeaf: true, + ); + main(List arguments) { if (arguments.contains("--testee")) { setFfiNativeResolverForTest(getRootLibraryUrl()); @@ -60,8 +69,13 @@ main(List arguments) { // Still we want to use it here to test data race detection. unsafeSetSharedTo(getRootLibraryUrl(), "box", List.filled(1, 0)); - print(box); // side effect initialization - Isolate.spawn(child, null); + // Avoid synchronizing via lazy compilation and initialization. + usleep(0); + box![0] += 0; + + var port = new RawReceivePort(); + port.handler = (_) => port.close(); + Isolate.spawn(child, port.sendPort); dataRaceFromMain(); return; } diff --git a/runtime/tests/vm/dart/tsan/field_data_race_no_sanitize_test.dart b/runtime/tests/vm/dart/tsan/field_data_race_no_sanitize_test.dart index c1238e4e02d..06d7045b735 100644 --- a/runtime/tests/vm/dart/tsan/field_data_race_no_sanitize_test.dart +++ b/runtime/tests/vm/dart/tsan/field_data_race_no_sanitize_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// VMOptions=--experimental-shared-data +// VMOptions=--experimental-shared-data --no-osr --no-background-compilation import "dart:ffi"; import "dart:io"; @@ -20,29 +20,31 @@ class Box { @pragma("vm:shared") Box? box; -@pragma("vm:never-inline") -noopt() {} - @pragma("vm:never-inline") dataRaceFromMain() { final localBox = box!; - for (var i = 0; i < 1000000; i++) { - localBox.foo += 1; - noopt(); + for (var i = 0; i < 50000; i++) { + usleep(100); + var t = localBox.foo; + usleep(100); + localBox.foo = t + 1; } } @pragma("vm:never-inline") dataRaceFromChild() { final localBox = box!; - for (var i = 0; i < 1000000; i++) { - localBox.foo += 1; - noopt(); + for (var i = 0; i < 50000; i++) { + usleep(100); + var t = localBox.foo; + usleep(100); + localBox.foo = t + 1; } } -child(_) { +child(replyPort) { dataRaceFromChild(); + replyPort.send(null); } final nativeLib = dlopenPlatformSpecific('ffi_test_functions'); @@ -58,12 +60,25 @@ final setFfiNativeResolverForTest = nativeLib @Native(symbol: 'UnsafeSetSharedTo') external int unsafeSetSharedTo(Object library_name, String name, Object value); +// Leaf: we don't want the two threads to synchronize via safepoint. +final usleep = DynamicLibrary.process() + .lookupFunction( + 'usleep', + isLeaf: true, + ); + main(List arguments) { if (arguments.contains("--testee")) { setFfiNativeResolverForTest(getRootLibraryUrl()); unsafeSetSharedTo(getRootLibraryUrl(), "box", Box()); - print(box); // side effect initialization - Isolate.spawn(child, null); + + // Avoid synchronizing via lazy compilation. + usleep(0); + box!.foo += 0; + + var port = new RawReceivePort(); + port.handler = (_) => port.close(); + Isolate.spawn(child, port.sendPort); dataRaceFromMain(); return; } diff --git a/runtime/tests/vm/dart/tsan/field_data_race_test.dart b/runtime/tests/vm/dart/tsan/field_data_race_test.dart index 9b7e7a1a524..0c9a7453841 100644 --- a/runtime/tests/vm/dart/tsan/field_data_race_test.dart +++ b/runtime/tests/vm/dart/tsan/field_data_race_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// VMOptions=--experimental-shared-data +// VMOptions=--experimental-shared-data --no-osr --no-background-compilation import "dart:ffi"; import "dart:io"; @@ -19,24 +19,25 @@ class Box { @pragma("vm:shared") Box? box; -@pragma("vm:never-inline") -noopt() {} - @pragma("vm:never-inline") dataRaceFromMain() { final localBox = box!; - for (var i = 0; i < 1000000; i++) { - localBox.foo += 1; - noopt(); + for (var i = 0; i < 50000; i++) { + usleep(100); + var t = localBox.foo; + usleep(100); + localBox.foo = t + 1; } } @pragma("vm:never-inline") dataRaceFromChild() { final localBox = box!; - for (var i = 0; i < 1000000; i++) { - localBox.foo += 1; - noopt(); + for (var i = 0; i < 50000; i++) { + usleep(100); + var t = localBox.foo; + usleep(100); + localBox.foo = t + 1; } } @@ -52,8 +53,9 @@ dataRaceFromChildCaller() => dataRaceFromChild(); @pragma("vm:never-inline") dataRaceFromChildCallerCaller() => dataRaceFromChildCaller(); -child(_) { +child(replyPort) { dataRaceFromChildCallerCaller(); + replyPort.send(null); } final nativeLib = dlopenPlatformSpecific('ffi_test_functions'); @@ -69,14 +71,27 @@ final setFfiNativeResolverForTest = nativeLib @Native(symbol: 'UnsafeSetSharedTo') external int unsafeSetSharedTo(Object library_name, String name, Object value); +// Leaf: we don't want the two threads to synchronize via safepoint. +final usleep = DynamicLibrary.process() + .lookupFunction( + 'usleep', + isLeaf: true, + ); + main(List arguments) { if (arguments.contains("--testee")) { setFfiNativeResolverForTest(getRootLibraryUrl()); // At this point List is not allowed to be stored in shaded fields. // Still we want to use it here to test data race detection. unsafeSetSharedTo(getRootLibraryUrl(), "box", Box()); - print(box); // side effect initialization - Isolate.spawn(child, null); + + // Avoid synchronizing via lazy compilation. + usleep(0); + box!.foo += 0; + + var port = new RawReceivePort(); + port.handler = (_) => port.close(); + Isolate.spawn(child, port.sendPort); dataRaceFromMainCallerCaller(); return; } diff --git a/runtime/tests/vm/dart/tsan/typed_data_race_test.dart b/runtime/tests/vm/dart/tsan/typed_data_race_test.dart index cc174ea781a..0e39989f585 100644 --- a/runtime/tests/vm/dart/tsan/typed_data_race_test.dart +++ b/runtime/tests/vm/dart/tsan/typed_data_race_test.dart @@ -2,8 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// VMOptions=--experimental-shared-data +// VMOptions=--experimental-shared-data --no-osr --no-background-compilation +import "dart:ffi"; import "dart:io"; import "dart:isolate"; import "dart:typed_data"; @@ -12,35 +13,49 @@ import "package:expect/expect.dart"; @pragma("vm:shared") Uint8List box = Uint8List(1); -@pragma("vm:never-inline") -noopt() {} - @pragma("vm:never-inline") dataRaceFromMain() { final localBox = box; - for (var i = 0; i < 10000000; i++) { - localBox[0] += 1; - noopt(); + for (var i = 0; i < 50000; i++) { + usleep(100); + var t = localBox[0]; + usleep(100); + localBox[0] = t + 1; } } @pragma("vm:never-inline") dataRaceFromChild() { final localBox = box; - for (var i = 0; i < 10000000; i++) { - localBox[0] += 1; - noopt(); + for (var i = 0; i < 50000; i++) { + usleep(100); + var t = localBox[0]; + usleep(100); + localBox[0] = t + 1; } } -child(_) { +child(replyPort) { dataRaceFromChild(); + replyPort.send(null); } +// Leaf: we don't want the two threads to synchronize via safepoint. +final usleep = DynamicLibrary.process() + .lookupFunction( + 'usleep', + isLeaf: true, + ); + main(List arguments) { if (arguments.contains("--testee")) { - print(box); // side effect initialization - Isolate.spawn(child, null); + // Avoid synchronizing via lazy compilation and initialization. + usleep(0); + box![0] += 0; + + var port = new RawReceivePort(); + port.handler = (_) => port.close(); + Isolate.spawn(child, port.sendPort); dataRaceFromMain(); return; }