Async: add sh_ptr<ContinuationChainLink> to Callback<>

This change enables us to finally implement the tracing of
continuations backward from the point of acquisition for deadlock
debugging.
This commit is contained in:
2025-09-27 18:30:09 -04:00
parent 2212aec080
commit 782bcd4567
26 changed files with 384 additions and 269 deletions
+53 -42
View File
@@ -2,6 +2,7 @@
#include <opts.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <mind.h>
#include <componentThread.h>
#include <director/director.h>
@@ -89,7 +90,7 @@ class Mind::MindLifetimeMgmtOp
public:
MindLifetimeMgmtOp(
Mind &parent, const std::shared_ptr<ComponentThread> &caller,
mindLifetimeMgmtOpCbFn callback)
Callback<mindLifetimeMgmtOpCbFn> callback)
: PostedAsynchronousContinuation<mindLifetimeMgmtOpCbFn>(
caller, callback),
parent(parent)
@@ -105,9 +106,9 @@ public:
{
/* Jolt the threads, then start them */
parent.joltAllMindThreadsReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::initializeReq2,
context.get(), context));
context.get(), context)});
}
void initializeReq2(
@@ -117,9 +118,9 @@ public:
std::cout << "Mrntt: All mind threads JOLTed." << "\n";
parent.startAllMindThreadsReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::initializeReq3,
context.get(), context));
context.get(), context)});
}
void initializeReq3(
@@ -129,9 +130,9 @@ public:
std::cout << "Mrntt: All mind threads started." << "\n";
parent.body.initializeReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::initializeReq4,
context.get(), context, std::placeholders::_1));
context.get(), context, std::placeholders::_1)});
}
void initializeReq4(
@@ -148,9 +149,9 @@ public:
)
{
parent.body.finalizeReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::finalizeReq2,
context.get(), context, std::placeholders::_1));
context.get(), context, std::placeholders::_1)});
}
void finalizeReq2(
@@ -169,9 +170,9 @@ public:
* messages from mrntt after processing the exit request.
*/
parent.joltAllMindThreadsReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::finalizeReq3,
context.get(), context));
context.get(), context)});
}
void finalizeReq3(
@@ -181,9 +182,9 @@ public:
std::cout << "Mrntt: All mind threads JOLTed for finalization." << "\n";
parent.exitAllMindThreadsReq(
std::bind(
{context, std::bind(
&MindLifetimeMgmtOp::finalizeReq4,
context.get(), context));
context.get(), context)});
}
void finalizeReq4(
@@ -195,7 +196,7 @@ public:
}
};
void Mind::initializeReq(mindLifetimeMgmtOpCbFn callback)
void Mind::initializeReq(Callback<mindLifetimeMgmtOpCbFn> callback)
{
/* Distribute threads across available CPUs */
try
@@ -219,7 +220,7 @@ void Mind::initializeReq(mindLifetimeMgmtOpCbFn callback)
request.get(), request));
}
void Mind::finalizeReq(mindLifetimeMgmtOpCbFn callback)
void Mind::finalizeReq(Callback<mindLifetimeMgmtOpCbFn> callback)
{
const auto& caller = ComponentThread::getSelf();
auto request = std::make_shared<MindLifetimeMgmtOp>(
@@ -258,7 +259,7 @@ class Mind::MindThreadLifetimeMgmtOp
public:
MindThreadLifetimeMgmtOp(
Mind &parent,unsigned int nThreads,
mindThreadLifetimeMgmtOpCbFn callback)
Callback<mindThreadLifetimeMgmtOpCbFn> callback)
: NonPostedAsynchronousContinuation<mindThreadLifetimeMgmtOpCbFn>(callback),
loop(nThreads),
parent(parent)
@@ -311,21 +312,23 @@ public:
}
};
void Mind::joltAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::joltAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
if (threadsHaveBeenJolted)
{
std::cout << "Mrntt: All mind threads already JOLTed. "
<< "Skipping JOLT request." << "\n";
callback();
callback.callbackFn();
return;
}
// If no threads, set flag and call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
threadsHaveBeenJolted = true;
callback();
callback.callbackFn();
return;
}
@@ -336,19 +339,21 @@ void Mind::joltAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->joltThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::joltAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}
// Thread management methods (moved from ComponentThread)
void Mind::startAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::startAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
// If no threads, call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
callback();
callback.callbackFn();
return;
}
@@ -359,18 +364,20 @@ void Mind::startAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->startThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}
void Mind::pauseAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::pauseAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
// If no threads, call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
callback();
callback.callbackFn();
return;
}
@@ -381,18 +388,20 @@ void Mind::pauseAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->pauseThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}
void Mind::resumeAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::resumeAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
// If no threads, call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
callback();
callback.callbackFn();
return;
}
@@ -403,18 +412,20 @@ void Mind::resumeAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->resumeThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}
void Mind::exitAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
void Mind::exitAllMindThreadsReq(
Callback<mindThreadLifetimeMgmtOpCbFn> callback
)
{
// If no threads, call callback immediately
if (componentThreads.size() == 0 && callback)
if (componentThreads.size() == 0 && callback.callbackFn)
{
callback();
callback.callbackFn();
return;
}
@@ -425,9 +436,9 @@ void Mind::exitAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback)
for (auto& thread : componentThreads)
{
thread->exitThreadReq(
std::bind(
{request, std::bind(
&MindThreadLifetimeMgmtOp::executeGenericOpOnAllMindThreadsReq1,
request.get(), request));
request.get(), request)});
}
}