summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-11-20 23:49:50 (GMT)
committerBrad King <brad.king@kitware.com>2023-11-21 17:37:53 (GMT)
commite528cd795fb33775f326af87628370d7798fab10 (patch)
treec0b761440dcd325a44ee74c81cdc6600e3ef2115
parent9d8415c17bff2319aa5eb9cbd272b557160d9efc (diff)
downloadCMake-e528cd795fb33775f326af87628370d7798fab10.zip
CMake-e528cd795fb33775f326af87628370d7798fab10.tar.gz
CMake-e528cd795fb33775f326af87628370d7798fab10.tar.bz2
cmCTestMultiProcessHandler: Start new tests asynchronously
When a test finishes, defer starting new tests until the next loop iteration. That way, if multiple tests finish in a single loop iteration, we can free all of their resources first, and then start a new batch of tests.
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx17
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h2
2 files changed, 17 insertions, 2 deletions
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index bb6bb9d..a673370 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -128,12 +128,14 @@ bool cmCTestMultiProcessHandler::Complete()
void cmCTestMultiProcessHandler::InitializeLoop()
{
this->Loop.init();
+ this->StartNextTestsOnIdle_.init(*this->Loop, this);
this->StartNextTestsOnTimer_.init(*this->Loop, this);
}
void cmCTestMultiProcessHandler::FinalizeLoop()
{
this->StartNextTestsOnTimer_.reset();
+ this->StartNextTestsOnIdle_.reset();
this->Loop.reset();
}
@@ -146,7 +148,7 @@ void cmCTestMultiProcessHandler::RunTests()
this->TestHandler->SetMaxIndex(this->FindMaxIndex());
this->InitializeLoop();
- this->StartNextTests();
+ this->StartNextTestsOnIdle();
uv_run(this->Loop, UV_RUN_DEFAULT);
this->FinalizeLoop();
@@ -468,6 +470,7 @@ void cmCTestMultiProcessHandler::StartNextTests()
{
// One or more events may be scheduled to call this method again.
// Since this method has been called they are no longer needed.
+ this->StartNextTestsOnIdle_.stop();
this->StartNextTestsOnTimer_.stop();
if (this->PendingTests.empty() || this->CheckStopTimePassed() ||
@@ -624,6 +627,16 @@ void cmCTestMultiProcessHandler::StartNextTests()
}
}
+void cmCTestMultiProcessHandler::StartNextTestsOnIdle()
+{
+ // Start more tests on the next loop iteration.
+ this->StartNextTestsOnIdle_.start([](uv_idle_t* idle) {
+ uv_idle_stop(idle);
+ auto* self = static_cast<cmCTestMultiProcessHandler*>(idle->data);
+ self->StartNextTests();
+ });
+}
+
void cmCTestMultiProcessHandler::StartNextTestsOnTimer()
{
// Wait between 1 and 5 seconds before trying again.
@@ -682,7 +695,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess(
runner.reset();
if (started) {
- this->StartNextTests();
+ this->StartNextTestsOnIdle();
}
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index cac35e3..cc230e7 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -130,6 +130,7 @@ protected:
void ErasePendingTest(int index);
void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);
+ void StartNextTestsOnIdle();
void StartNextTestsOnTimer();
void RemoveTest(int index);
@@ -207,6 +208,7 @@ protected:
unsigned long TestLoad;
unsigned long FakeLoadForTesting;
cm::uv_loop_ptr Loop;
+ cm::uv_idle_ptr StartNextTestsOnIdle_;
cm::uv_timer_ptr StartNextTestsOnTimer_;
cmCTestTestHandler* TestHandler;
cmCTest* CTest;