spinscale: Move thread init/jolt/exit logic into PuppetApplication
This commit is contained in:
+34
-211
@@ -14,24 +14,25 @@
|
||||
namespace smo {
|
||||
|
||||
Mind::Mind(void)
|
||||
: componentThreads{
|
||||
std::make_shared<MindThread>(SmoThreadId::DIRECTOR, *this),
|
||||
std::make_shared<MindThread>(SmoThreadId::SIMULATOR, *this),
|
||||
std::make_shared<MindThread>(SmoThreadId::SUBCONSCIOUS, *this),
|
||||
std::make_shared<MindThread>(SmoThreadId::BODY, *this)
|
||||
: PuppetApplication(
|
||||
std::vector<std::shared_ptr<PuppetThread>>{
|
||||
std::make_shared<MindThread>(SmoThreadId::DIRECTOR, *this),
|
||||
std::make_shared<MindThread>(SmoThreadId::SIMULATOR, *this),
|
||||
std::make_shared<MindThread>(SmoThreadId::SUBCONSCIOUS, *this),
|
||||
std::make_shared<MindThread>(SmoThreadId::BODY, *this)
|
||||
#ifndef CONFIG_WORLD_USE_BODY_THREAD
|
||||
, std::make_shared<MindThread>(SmoThreadId::WORLD, *this)
|
||||
, std::make_shared<MindThread>(SmoThreadId::WORLD, *this)
|
||||
#endif
|
||||
},
|
||||
director(*this, componentThreads[0]),
|
||||
canvas(*this, componentThreads[1]),
|
||||
subconscious(*this, componentThreads[2]),
|
||||
body(*this, componentThreads[3]),
|
||||
}),
|
||||
director(*this, std::static_pointer_cast<MindThread>(componentThreads[0])),
|
||||
canvas(*this, std::static_pointer_cast<MindThread>(componentThreads[1])),
|
||||
subconscious(*this, std::static_pointer_cast<MindThread>(componentThreads[2])),
|
||||
body(*this, std::static_pointer_cast<MindThread>(componentThreads[3])),
|
||||
world(*this,
|
||||
#ifndef CONFIG_WORLD_USE_BODY_THREAD
|
||||
componentThreads[4]
|
||||
std::static_pointer_cast<MindThread>(componentThreads[4])
|
||||
#else
|
||||
componentThreads[3]
|
||||
std::static_pointer_cast<MindThread>(componentThreads[3])
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -49,8 +50,11 @@ Mind::getComponentThread(ThreadId id) const
|
||||
}
|
||||
|
||||
// Search through the vector for the thread with matching id
|
||||
for (auto& thread : componentThreads) {
|
||||
if (thread->id == id) { return thread; }
|
||||
for (auto& thread : componentThreads)
|
||||
{
|
||||
if (thread->id == id) {
|
||||
return std::static_pointer_cast<MindThread>(thread);
|
||||
}
|
||||
}
|
||||
|
||||
// Throw exception if no thread found
|
||||
@@ -70,8 +74,11 @@ Mind::getComponentThread(const std::string& name) const
|
||||
"getComponentThread");
|
||||
}
|
||||
|
||||
for (auto& thread : componentThreads) {
|
||||
if (thread->name == name) { return thread; }
|
||||
for (auto& thread : componentThreads)
|
||||
{
|
||||
if (thread->name == name) {
|
||||
return std::static_pointer_cast<MindThread>(thread);
|
||||
}
|
||||
}
|
||||
|
||||
// Throw exception if no thread found
|
||||
@@ -82,7 +89,12 @@ Mind::getComponentThread(const std::string& name) const
|
||||
std::vector<std::shared_ptr<MindThread>>
|
||||
Mind::getMindThreads() const
|
||||
{
|
||||
return componentThreads;
|
||||
std::vector<std::shared_ptr<MindThread>> mindThreads;
|
||||
mindThreads.reserve(componentThreads.size());
|
||||
for (auto& thread : componentThreads) {
|
||||
mindThreads.push_back(std::static_pointer_cast<MindThread>(thread));
|
||||
}
|
||||
return mindThreads;
|
||||
}
|
||||
|
||||
class Mind::MindLifetimeMgmtOp
|
||||
@@ -106,7 +118,7 @@ public:
|
||||
)
|
||||
{
|
||||
/* Jolt the threads, then start them */
|
||||
parent.joltAllMindThreadsReq(
|
||||
parent.joltAllPuppetThreadsReq(
|
||||
{context, std::bind(
|
||||
&MindLifetimeMgmtOp::initializeReq2,
|
||||
context.get(), context)});
|
||||
@@ -118,7 +130,7 @@ public:
|
||||
{
|
||||
std::cout << "Mrntt: All mind threads JOLTed." << "\n";
|
||||
|
||||
parent.startAllMindThreadsReq(
|
||||
parent.startAllPuppetThreadsReq(
|
||||
{context, std::bind(
|
||||
&MindLifetimeMgmtOp::initializeReq3,
|
||||
context.get(), context)});
|
||||
@@ -170,7 +182,7 @@ public:
|
||||
* otherwise they'll just enter their main loops and wait for control
|
||||
* messages from mrntt after processing the exit request.
|
||||
*/
|
||||
parent.joltAllMindThreadsReq(
|
||||
parent.joltAllPuppetThreadsReq(
|
||||
{context, std::bind(
|
||||
&MindLifetimeMgmtOp::finalizeReq3,
|
||||
context.get(), context)});
|
||||
@@ -182,7 +194,7 @@ public:
|
||||
{
|
||||
std::cout << "Mrntt: All mind threads JOLTed for finalization." << "\n";
|
||||
|
||||
parent.exitAllMindThreadsReq(
|
||||
parent.exitAllPuppetThreadsReq(
|
||||
{context, std::bind(
|
||||
&MindLifetimeMgmtOp::finalizeReq4,
|
||||
context.get(), context)});
|
||||
@@ -254,193 +266,4 @@ void Mind::distributeAndPinThreadsAcrossCpus()
|
||||
<< "across " << cpuCount << " CPUs\n";
|
||||
}
|
||||
|
||||
class Mind::MindThreadLifetimeMgmtOp
|
||||
: public NonPostedAsynchronousContinuation<mindThreadLifetimeMgmtOpCbFn>
|
||||
{
|
||||
public:
|
||||
MindThreadLifetimeMgmtOp(
|
||||
Mind &parent,unsigned int nThreads,
|
||||
Callback<mindThreadLifetimeMgmtOpCbFn> callback)
|
||||
: NonPostedAsynchronousContinuation<mindThreadLifetimeMgmtOpCbFn>(callback),
|
||||
loop(nThreads),
|
||||
parent(parent)
|
||||
{}
|
||||
|
||||
public:
|
||||
AsynchronousLoop loop;
|
||||
Mind &parent;
|
||||
|
||||
public:
|
||||
void joltAllMindThreadsReq1(
|
||||
[[maybe_unused]] std::shared_ptr<MindThreadLifetimeMgmtOp> context
|
||||
)
|
||||
{
|
||||
loop.incrementSuccessOrFailureDueTo(true);
|
||||
if (!loop.isComplete()) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent.threadsHaveBeenJolted = true;
|
||||
callOriginalCb();
|
||||
}
|
||||
|
||||
void executeGenericOpOnAllMindThreadsReq1(
|
||||
[[maybe_unused]] std::shared_ptr<MindThreadLifetimeMgmtOp> context
|
||||
)
|
||||
{
|
||||
loop.incrementSuccessOrFailureDueTo(true);
|
||||
if (!loop.isComplete()) {
|
||||
return;
|
||||
}
|
||||
|
||||
callOriginalCb();
|
||||
}
|
||||
|
||||
void exitAllMindThreadsReq1(
|
||||
[[maybe_unused]] std::shared_ptr<MindThreadLifetimeMgmtOp> context
|
||||
)
|
||||
{
|
||||
loop.incrementSuccessOrFailureDueTo(true);
|
||||
if (!loop.isComplete()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& thread : parent.componentThreads) {
|
||||
thread->thread.join();
|
||||
}
|
||||
|
||||
callOriginalCb();
|
||||
}
|
||||
};
|
||||
|
||||
void Mind::joltAllMindThreadsReq(
|
||||
Callback<mindThreadLifetimeMgmtOpCbFn> callback
|
||||
)
|
||||
{
|
||||
if (threadsHaveBeenJolted)
|
||||
{
|
||||
std::cout << "Mrntt: All mind threads already JOLTed. "
|
||||
<< "Skipping JOLT request." << "\n";
|
||||
callback.callbackFn();
|
||||
return;
|
||||
}
|
||||
|
||||
// If no threads, set flag and call callback immediately
|
||||
if (componentThreads.size() == 0 && callback.callbackFn)
|
||||
{
|
||||
threadsHaveBeenJolted = true;
|
||||
callback.callbackFn();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a counter to track when all threads have been jolted
|
||||
auto request = std::make_shared<MindThreadLifetimeMgmtOp>(
|
||||
*this, componentThreads.size(), callback);
|
||||
|
||||
for (auto& thread : componentThreads)
|
||||
{
|
||||
thread->joltThreadReq(
|
||||
{request, std::bind(
|
||||
&MindThreadLifetimeMgmtOp::joltAllMindThreadsReq1,
|
||||
request.get(), request)});
|
||||
}
|
||||
}
|
||||
|
||||
// Thread management methods (moved from ComponentThread)
|
||||
void Mind::startAllMindThreadsReq(
|
||||
Callback<mindThreadLifetimeMgmtOpCbFn> callback
|
||||
)
|
||||
{
|
||||
// If no threads, call callback immediately
|
||||
if (componentThreads.size() == 0 && callback.callbackFn)
|
||||
{
|
||||
callback.callbackFn();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a counter to track when all threads have started
|
||||
auto request = std::make_shared<MindThreadLifetimeMgmtOp>(
|
||||
*this, componentThreads.size(), callback);
|
||||
|
||||
for (auto& thread : componentThreads)
|
||||
{
|
||||
thread->startThreadReq(
|
||||
{request, std::bind(
|
||||
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
|
||||
request.get(), request)});
|
||||
}
|
||||
}
|
||||
|
||||
void Mind::pauseAllMindThreadsReq(
|
||||
Callback<mindThreadLifetimeMgmtOpCbFn> callback
|
||||
)
|
||||
{
|
||||
// If no threads, call callback immediately
|
||||
if (componentThreads.size() == 0 && callback.callbackFn)
|
||||
{
|
||||
callback.callbackFn();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a counter to track when all threads have paused
|
||||
auto request = std::make_shared<MindThreadLifetimeMgmtOp>(
|
||||
*this, componentThreads.size(), callback);
|
||||
|
||||
for (auto& thread : componentThreads)
|
||||
{
|
||||
thread->pauseThreadReq(
|
||||
{request, std::bind(
|
||||
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
|
||||
request.get(), request)});
|
||||
}
|
||||
}
|
||||
|
||||
void Mind::resumeAllMindThreadsReq(
|
||||
Callback<mindThreadLifetimeMgmtOpCbFn> callback
|
||||
)
|
||||
{
|
||||
// If no threads, call callback immediately
|
||||
if (componentThreads.size() == 0 && callback.callbackFn)
|
||||
{
|
||||
callback.callbackFn();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a counter to track when all threads have resumed
|
||||
auto request = std::make_shared<MindThreadLifetimeMgmtOp>(
|
||||
*this, componentThreads.size(), callback);
|
||||
|
||||
for (auto& thread : componentThreads)
|
||||
{
|
||||
thread->resumeThreadReq(
|
||||
{request, std::bind(
|
||||
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
|
||||
request.get(), request)});
|
||||
}
|
||||
}
|
||||
|
||||
void Mind::exitAllMindThreadsReq(
|
||||
Callback<mindThreadLifetimeMgmtOpCbFn> callback
|
||||
)
|
||||
{
|
||||
// If no threads, call callback immediately
|
||||
if (componentThreads.size() == 0 && callback.callbackFn)
|
||||
{
|
||||
callback.callbackFn();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a counter to track when all threads have exited
|
||||
auto request = std::make_shared<MindThreadLifetimeMgmtOp>(
|
||||
*this, componentThreads.size(), callback);
|
||||
|
||||
for (auto& thread : componentThreads)
|
||||
{
|
||||
thread->exitThreadReq(
|
||||
{request, std::bind(
|
||||
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
|
||||
request.get(), request)});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace smo
|
||||
|
||||
Reference in New Issue
Block a user