summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-11-15 18:55:35 (GMT)
committerBrad King <brad.king@kitware.com>2023-12-03 13:30:07 (GMT)
commit80fe56c481a5e69cd5ee4fbbbd77266579f96d98 (patch)
tree0f6c1657aa64a25265264bcefd792abd28758d59 /Source
parent5396f4a9a30d11ae17a1a991e54d4e0714457590 (diff)
downloadCMake-80fe56c481a5e69cd5ee4fbbbd77266579f96d98.zip
CMake-80fe56c481a5e69cd5ee4fbbbd77266579f96d98.tar.gz
CMake-80fe56c481a5e69cd5ee4fbbbd77266579f96d98.tar.bz2
ctest: Add support for running under a make job server on POSIX systems
Share job slots with the job server by acquiring a token before running each test, and releasing the token when the test finishes.
Diffstat (limited to 'Source')
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx33
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h10
2 files changed, 43 insertions, 0 deletions
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index be210f4..7b72f30 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -40,6 +40,7 @@
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmUVJobServerClient.h"
#include "cmWorkingDirectory.h"
namespace cmsys {
@@ -130,10 +131,19 @@ void cmCTestMultiProcessHandler::InitializeLoop()
this->Loop.init();
this->StartNextTestsOnIdle_.init(*this->Loop, this);
this->StartNextTestsOnTimer_.init(*this->Loop, this);
+
+ this->JobServerClient = cmUVJobServerClient::Connect(
+ *this->Loop, /*onToken=*/[this]() { this->JobServerReceivedToken(); },
+ /*onDisconnect=*/nullptr);
+ if (this->JobServerClient) {
+ cmCTestLog(this->CTest, OUTPUT,
+ "Connected to MAKE jobserver" << std::endl);
+ }
}
void cmCTestMultiProcessHandler::FinalizeLoop()
{
+ this->JobServerClient.reset();
this->StartNextTestsOnTimer_.reset();
this->StartNextTestsOnIdle_.reset();
this->Loop.reset();
@@ -461,6 +471,26 @@ std::string cmCTestMultiProcessHandler::GetName(int test)
void cmCTestMultiProcessHandler::StartTest(int test)
{
+ if (this->JobServerClient) {
+ // There is a job server. Request a token and queue the test to run
+ // when a token is received. Note that if we do not get a token right
+ // away it's possible that the system load will be higher when the
+ // token is received and we may violate the test-load limit. However,
+ // this is unlikely because if we do not get a token right away, some
+ // other job that's currently running must finish before we get one.
+ this->JobServerClient->RequestToken();
+ this->JobServerQueuedTests.emplace_back(test);
+ } else {
+ // There is no job server. Start the test now.
+ this->StartTestProcess(test);
+ }
+}
+
+void cmCTestMultiProcessHandler::JobServerReceivedToken()
+{
+ assert(!this->JobServerQueuedTests.empty());
+ int test = this->JobServerQueuedTests.front();
+ this->JobServerQueuedTests.pop_front();
this->StartTestProcess(test);
}
@@ -692,6 +722,9 @@ void cmCTestMultiProcessHandler::FinishTestProcess(
runner.reset();
+ if (this->JobServerClient) {
+ this->JobServerClient->ReleaseToken();
+ }
this->StartNextTestsOnIdle();
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 1be04aa..02589ca 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -19,6 +19,7 @@
#include "cmCTestResourceSpec.h"
#include "cmCTestTestHandler.h"
#include "cmUVHandlePtr.h"
+#include "cmUVJobServerClient.h"
struct cmCTestBinPackerAllocation;
class cmCTestRunTest;
@@ -204,6 +205,15 @@ protected:
cmCTestResourceAllocator ResourceAllocator;
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
+
+ // 'make' jobserver client. If connected, we acquire a token
+ // for each test before running its process.
+ cm::optional<cmUVJobServerClient> JobServerClient;
+ // List of tests that are queued to run when a token is available.
+ std::list<int> JobServerQueuedTests;
+ // Callback invoked when a token is received.
+ void JobServerReceivedToken();
+
unsigned long TestLoad;
unsigned long FakeLoadForTesting;
cm::uv_loop_ptr Loop;