OClCollMeshEngn: Use shouldAcceptRequests stop/finalize() pattern

This makes the stop() method capable of synchronously stopping all
engine/server-type async services which don't act in a self-moved
fashion but instead wait for a request.
This commit is contained in:
2025-11-14 01:41:03 -04:00
parent 324e3d1f6a
commit a1625eb562
2 changed files with 86 additions and 36 deletions
@@ -92,8 +92,9 @@ slotCompactorProgram(nullptr), collateProgram(nullptr),
slotCompactorKernel(nullptr), collateKernel(nullptr),
clAssemblyBuffer(nullptr),
clCollationBuffer(nullptr),
compactIsSetup(false), compactIsRunning(false),
collateIsSetup(false), collateIsRunning(false),
shouldAcceptRequests(false),
compactIsRunning(false),
collateIsRunning(false),
currentCompactKernelEvent(nullptr), currentCollateKernelEvent(nullptr),
assemblyBufferPtr(nullptr),
assemblyBufferSize(0),
@@ -112,8 +113,14 @@ OpenClCollatingAndMeshingEngine::~OpenClCollatingAndMeshingEngine()
bool OpenClCollatingAndMeshingEngine::setup()
{
if (compactIsSetup && collateIsSetup) {
return true;
// Defensive check to prevent double-calling
{
SpinLock::Guard lock(shouldAcceptRequestsLock);
if (shouldAcceptRequests)
{
throw std::runtime_error(std::string(__func__) + ": setup() called "
"while already set up");
}
}
cl_int err;
@@ -235,8 +242,7 @@ bool OpenClCollatingAndMeshingEngine::setup()
goto cleanup;
}
compactIsSetup = true;
collateIsSetup = true;
shouldAcceptRequests = true;
return true;
cleanup:
@@ -246,8 +252,13 @@ cleanup:
void OpenClCollatingAndMeshingEngine::finalize()
{
// Call stop() first
stop();
// Call stop() to set shouldAcceptRequests to false and get previous state
bool wasAcceptingRequests = stop();
(void)wasAcceptingRequests;
// Complete any running kernels
compactKernelComplete();
collateKernelComplete();
// Release OpenCL buffers in reverse order
if (clCollationBuffer)
@@ -302,9 +313,7 @@ void OpenClCollatingAndMeshingEngine::finalize()
// Reset state variables
device = nullptr;
platform = nullptr;
compactIsSetup = false;
compactIsRunning = false;
collateIsSetup = false;
collateIsRunning = false;
currentCompactKernelEvent = nullptr;
currentCollateKernelEvent = nullptr;
@@ -400,7 +409,6 @@ bool OpenClCollatingAndMeshingEngine::startCompactKernel(
1, // globalWorkSize
compactKernelEventCallback,
"slotCompactor",
compactIsSetup,
compactIsRunning);
if (!success) { return false; }
@@ -459,7 +467,6 @@ bool OpenClCollatingAndMeshingEngine::startCollateKernel(
globalWorkSize,
collateKernelEventCallback,
"collateDgrams",
collateIsSetup,
collateIsRunning);
if (!success) { return false; }
@@ -683,13 +690,16 @@ bool OpenClCollatingAndMeshingEngine::setupCollateDgramsArgs(
return true;
}
void OpenClCollatingAndMeshingEngine::stop()
bool OpenClCollatingAndMeshingEngine::stop()
{
stopCompactKernel();
stopCollateKernel();
// Acquire and release lock tightly around setting the flag
SpinLock::Guard lock(shouldAcceptRequestsLock);
bool wasAcceptingRequests = shouldAcceptRequests;
shouldAcceptRequests = false;
return wasAcceptingRequests;
}
void OpenClCollatingAndMeshingEngine::stopCompactKernel()
void OpenClCollatingAndMeshingEngine::compactKernelComplete()
{
/** EXPLANATION:
* Technically we should only need to do this if we plan to read the
@@ -706,12 +716,12 @@ void OpenClCollatingAndMeshingEngine::stopCompactKernel()
clWaitForEvents(1, &currentCompactKernelEvent);
clReleaseEvent(currentCompactKernelEvent);
currentCompactKernelEvent = nullptr;
compactIsRunning = false;
}
compactKernelCb = [](cl_int){};
compactIsRunning = false;
}
void OpenClCollatingAndMeshingEngine::stopCollateKernel()
void OpenClCollatingAndMeshingEngine::collateKernelComplete()
{
/** EXPLANATION:
* Technically we should only need to do this if we plan to read the
@@ -727,9 +737,9 @@ void OpenClCollatingAndMeshingEngine::stopCollateKernel()
clWaitForEvents(1, &currentCollateKernelEvent);
clReleaseEvent(currentCollateKernelEvent);
currentCollateKernelEvent = nullptr;
collateIsRunning = false;
}
collateKernelCb = [](cl_int){};
collateIsRunning = false;
}
bool OpenClCollatingAndMeshingEngine::mapBuffer(
@@ -869,6 +879,13 @@ public:
void compactCollateAndMeshFrameReq1_doCompact_posted(
std::shared_ptr<CompactCollateAndMeshFrameReq> context)
{
SpinLock::Guard lock(engine.shouldAcceptRequestsLock);
if (!engine.shouldAcceptRequests)
{
callOriginalCallback(false);
return;
}
// Record compact kernel start time
engine.compactKernelStartTime = std::chrono::high_resolution_clock::now();
@@ -883,7 +900,7 @@ public:
if (!success)
{
engine.stopCompactKernel();
engine.compactKernelComplete();
callOriginalCallback(false);
return;
}
@@ -893,7 +910,20 @@ public:
std::shared_ptr<CompactCollateAndMeshFrameReq> context,
cl_int compactStatus)
{
engine.stopCompactKernel();
SpinLock::Guard lock(engine.shouldAcceptRequestsLock);
if (!engine.shouldAcceptRequests)
{
/** EXPLANATION:
* We intentionally don't call compactKernelComplete() here because
* if shouldAcceptRequests is false, then the caller that called
* finalize() will also be forced to call compactKernelComplete()
* inside of finalize().
*/
callOriginalCallback(false);
return;
}
engine.compactKernelComplete();
// Record compact kernel end time
engine.compactKernelEndTime = std::chrono::high_resolution_clock::now();
@@ -914,12 +944,20 @@ public:
}
#endif
lock.unlockPrematurely();
context->compactCollateAndMeshFrameReq3_doCollate_posted(context);
}
void compactCollateAndMeshFrameReq3_doCollate_posted(
std::shared_ptr<CompactCollateAndMeshFrameReq> context)
{
SpinLock::Guard lock(engine.shouldAcceptRequestsLock);
if (!engine.shouldAcceptRequests)
{
callOriginalCallback(false);
return;
}
// Record collate kernel start time
engine.collateKernelStartTime = std::chrono::high_resolution_clock::now();
@@ -933,7 +971,7 @@ public:
if (!success)
{
engine.stopCollateKernel();
engine.collateKernelComplete();
callOriginalCallback(false);
return;
}
@@ -943,7 +981,17 @@ public:
[[maybe_unused]] std::shared_ptr<CompactCollateAndMeshFrameReq> context,
cl_int collateStatus)
{
engine.stopCollateKernel();
SpinLock::Guard lock(engine.shouldAcceptRequestsLock);
if (!engine.shouldAcceptRequests)
{
/* We intentionally don't call collateKernelComplete() here for the
* same reason as above.
*/
callOriginalCallback(false);
return;
}
engine.collateKernelComplete();
// Record collate kernel end time
engine.collateKernelEndTime = std::chrono::high_resolution_clock::now();
@@ -986,6 +1034,15 @@ void OpenClCollatingAndMeshingEngine::compactCollateAndMeshFrameReq(
AsynchronousLoop& asyncLoop, StimulusFrame& stimulusFrame,
Callback<compactCollateAndMeshFrameReqCbFn> callback)
{
{
SpinLock::Guard lock(shouldAcceptRequestsLock);
if (!shouldAcceptRequests)
{
callback.callbackFn(false, stimulusFrame);
return;
}
}
auto caller = smoHooksPtr->ComponentThread_getSelf();
auto request = std::make_shared<CompactCollateAndMeshFrameReq>(
*this, asyncLoop, stimulusFrame,