[vm] Make vm/cc/SafepointOperation_SafepointPointTest robust to unfavorable scheduling.
TEST=ci
Change-Id: Icb03a30cbcbf181fa07c939b606524b29ac70747
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/416400
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
diff --git a/runtime/vm/heap/safepoint_test.cc b/runtime/vm/heap/safepoint_test.cc
index eb1612d..362db62 100644
--- a/runtime/vm/heap/safepoint_test.cc
+++ b/runtime/vm/heap/safepoint_test.cc
@@ -326,7 +326,7 @@
virtual void RunInternal() {
data_->WaitUntil(kStartLoop);
- uword last_sync = OS::GetCurrentTimeMillis();
+ uword last_sync = OS::GetCurrentMonotonicMicros();
while (!data()->IsIn(kPleaseExit)) {
OS::SleepMicros(100); // Make test avoid consuming 100% CPU x kTaskCount.
switch (data()->level) {
@@ -335,14 +335,14 @@
RuntimeCallDeoptScope no_deopt(
Thread::Current(), RuntimeCallDeoptAbility::kCannotLazyDeopt);
if (SafepointIfRequested(thread_, data()->gc_only_checkins)) {
- last_sync = OS::GetCurrentTimeMillis();
+ last_sync = OS::GetCurrentMonotonicMicros();
}
break;
}
case SafepointLevel::kGCAndDeopt: {
// This thread should join only GC and Deopt safepoint operations.
if (SafepointIfRequested(thread_, data()->deopt_checkin)) {
- last_sync = OS::GetCurrentTimeMillis();
+ last_sync = OS::GetCurrentMonotonicMicros();
}
break;
}
@@ -350,7 +350,7 @@
// This thread should join any safepoint operations.
ReloadParticipationScope allow_reload(thread_);
if (SafepointIfRequested(thread_, data()->reload_checkin)) {
- last_sync = OS::GetCurrentTimeMillis();
+ last_sync = OS::GetCurrentMonotonicMicros();
}
break;
}
@@ -367,8 +367,8 @@
// After being quite sure to not have joined deopt safepoint if we only
// support GC safepoints, we will eventually comply here to make main
// thread continue.
- const auto now = OS::GetCurrentTimeMillis();
- if ((now - last_sync) > 1000) {
+ const auto now = OS::GetCurrentMonotonicMicros();
+ if ((now - last_sync) > 1000000) {
ReloadParticipationScope allow_reload(thread_);
if (SafepointIfRequested(thread_, data()->timeout_checkin)) {
last_sync = now;
@@ -494,25 +494,27 @@
for (intptr_t i = 0; i < kTaskCount; i++) {
threads[i]->WaitUntil(CheckinTask::kExited);
}
+ // Unlucky scheduling may result in more timeout checkins than intended, but
+ // never checkins of otherwise the wrong type.
for (intptr_t i = 0; i < kTaskCount; ++i) {
switch (task_to_level(i)) {
case SafepointLevel::kGC:
- EXPECT_EQ(2, gc_only_checkins[i]);
- EXPECT_EQ(0, deopt_checkins[i]);
- EXPECT_EQ(0, reload_checkins[i]);
- EXPECT_EQ(4, timeout_checkins[i]);
+ EXPECT_LE(gc_only_checkins[i], 2);
+ EXPECT_EQ(deopt_checkins[i], 0);
+ EXPECT_EQ(reload_checkins[i], 0);
+ EXPECT_GE(timeout_checkins[i], 4);
break;
case SafepointLevel::kGCAndDeopt:
- EXPECT_EQ(0, gc_only_checkins[i]);
- EXPECT_EQ(4, deopt_checkins[i]);
- EXPECT_EQ(0, reload_checkins[i]);
- EXPECT_EQ(2, timeout_checkins[i]);
+ EXPECT_EQ(gc_only_checkins[i], 0);
+ EXPECT_LE(deopt_checkins[i], 4);
+ EXPECT_EQ(reload_checkins[i], 0);
+ EXPECT_GE(timeout_checkins[i], 2);
break;
case SafepointLevel::kGCAndDeoptAndReload:
- EXPECT_EQ(0, gc_only_checkins[i]);
- EXPECT_EQ(0, deopt_checkins[i]);
- EXPECT_EQ(6, reload_checkins[i]);
- EXPECT_EQ(0, timeout_checkins[i]);
+ EXPECT_EQ(gc_only_checkins[i], 0);
+ EXPECT_EQ(deopt_checkins[i], 0);
+ EXPECT_LE(reload_checkins[i], 6);
+ EXPECT_GE(timeout_checkins[i], 0);
break;
case SafepointLevel::kNumLevels:
case SafepointLevel::kNoSafepoint: