OClCollMeshEngn,PcloudStimProd: port to sscl::co coros
We've now ported the OpenClCollMeshEngn and PcloudStimProd::produceFrameReq portions of the Livox pipeline to coros.
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
#include <user/spMcRingBuffer.h>
|
||||
#include <componentThread.h>
|
||||
#include <spinscale/asynchronousLoop.h>
|
||||
#include <spinscale/co/invokers.h>
|
||||
#include <adapters/smo/assembleFrameAReq.h>
|
||||
#include <user/stimulusFrame.h>
|
||||
#include <user/frameAssemblyDesc.h>
|
||||
#include <livoxProto1/device.h>
|
||||
@@ -428,219 +430,205 @@ PcloudStimulusProducer::getOrCreateAttachedStimulusBuffer(
|
||||
|
||||
void PcloudStimulusProducer::stimFrameProductionTimesliceInd()
|
||||
{
|
||||
produceFrameReq({nullptr, nullptr});
|
||||
holdProduceFrameCReq();
|
||||
}
|
||||
|
||||
class PcloudStimulusProducer::ProduceFrameReq
|
||||
: public sscl::cps::PostedAsynchronousContinuation<produceFrameReqCbFn>
|
||||
struct AllowNextStimulusFrameGuard
|
||||
{
|
||||
private:
|
||||
PcloudStimulusProducer& pcloudProducer;
|
||||
sscl::AsynchronousLoop frameAssemblyResult;
|
||||
StimulusFrame& stimulusFrame;
|
||||
PcloudStimulusProducer& producer;
|
||||
|
||||
explicit AllowNextStimulusFrameGuard(PcloudStimulusProducer& _producer)
|
||||
: producer(_producer)
|
||||
{}
|
||||
|
||||
~AllowNextStimulusFrameGuard()
|
||||
{ producer.allowNextStimulusFrame(); }
|
||||
};
|
||||
|
||||
void PcloudStimulusProducer::holdProduceFrameCReq()
|
||||
{
|
||||
/** EXPLANATION:
|
||||
* We shouldn't acquire stimulusProducerCanceler.s.lock here because
|
||||
* this function is called from
|
||||
* StimulusProducer::stimFrameProductionTimesliceInd(), which is already
|
||||
* holding the lock.
|
||||
*/
|
||||
activeProduceFrameInvoker.emplace(produceFrameCReq(
|
||||
produceFrameExceptionPtr,
|
||||
[this]() { activeProduceFrameInvoker.reset(); }));
|
||||
}
|
||||
|
||||
sscl::co::NonViralNonPostingInvoker PcloudStimulusProducer::produceFrameCReq(
|
||||
[[maybe_unused]] std::exception_ptr& exceptionPtr,
|
||||
[[maybe_unused]] std::function<void()> completion)
|
||||
{
|
||||
AllowNextStimulusFrameGuard allowNextGuard(*this);
|
||||
StimulusFrame& stimulusFrame = tempStimulusFrame;
|
||||
sscl::AsynchronousLoop frameAssemblyResult(0);
|
||||
std::optional<std::reference_wrapper<StimulusFrame>> intensityStimFrame;
|
||||
std::optional<std::reference_wrapper<StimulusFrame>> lightAmbienceStimFrame;
|
||||
std::optional<std::reference_wrapper<StimulusFrame>> darkAmbienceStimFrame;
|
||||
|
||||
public:
|
||||
ProduceFrameReq(
|
||||
PcloudStimulusProducer& producer,
|
||||
const std::shared_ptr<sscl::ComponentThread>& caller,
|
||||
sscl::cps::Callback<produceFrameReqCbFn> cb)
|
||||
: sscl::cps::PostedAsynchronousContinuation<produceFrameReqCbFn>(caller, cb),
|
||||
pcloudProducer(producer),
|
||||
frameAssemblyResult(0),
|
||||
stimulusFrame(producer.tempStimulusFrame)
|
||||
{}
|
||||
auto& resumeIoContext = device->componentThread->getIoContext();
|
||||
|
||||
public:
|
||||
void callOriginalCallback()
|
||||
// produceFrameReq1_doAssemble_posted
|
||||
/** EXPLANATION:
|
||||
* stimFrameProductionTimesliceInd() is entered with
|
||||
* stimulusProducerCanceler.s.lock held; do not re-acquire here.
|
||||
*
|
||||
* This function is called from
|
||||
* StimulusProducer::stimFrameProductionTimesliceInd(), whose caller is
|
||||
* already holding the lock.
|
||||
*/
|
||||
if (stimulusProducerCanceler.isCancellationRequestedUnlocked())
|
||||
{ co_return; }
|
||||
|
||||
cpsBoundary::AssembleFrameResult assembleResult = co_await
|
||||
cpsBoundary::getAssembleFrameReqAReqAwaiter(
|
||||
resumeIoContext, ioUringAssemblyEngine);
|
||||
|
||||
// produceFrameReq2_assembleDone
|
||||
std::optional<AmbienceProductionDesc> lightAmbienceProductionDescDesc;
|
||||
std::optional<AmbienceProductionDesc> darkAmbienceProductionDescDesc;
|
||||
{
|
||||
pcloudProducer.allowNextStimulusFrame();
|
||||
callOriginalCb();
|
||||
}
|
||||
sscl::SpinLock::Guard guard(stimulusProducerCanceler.s.lock);
|
||||
if (stimulusProducerCanceler.isCancellationRequestedUnlocked())
|
||||
{ co_return; }
|
||||
|
||||
public:
|
||||
void produceFrameReq1_doAssemble_posted(
|
||||
std::shared_ptr<ProduceFrameReq> context)
|
||||
{
|
||||
sscl::SpinLock::Guard guard(
|
||||
pcloudProducer.stimulusProducerCanceler.s.lock);
|
||||
if (pcloudProducer.stimulusProducerCanceler
|
||||
.isCancellationRequestedUnlocked())
|
||||
if (!assembleResult.success)
|
||||
{
|
||||
callOriginalCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
pcloudProducer.ioUringAssemblyEngine.assembleFrameReq(
|
||||
{context, std::bind(
|
||||
&ProduceFrameReq::produceFrameReq2_assembleDone,
|
||||
context.get(), context,
|
||||
std::placeholders::_1, std::placeholders::_2)});
|
||||
}
|
||||
|
||||
void produceFrameReq2_assembleDone(
|
||||
std::shared_ptr<ProduceFrameReq> context,
|
||||
bool success, sscl::AsynchronousLoop loop)
|
||||
{
|
||||
sscl::SpinLock::Guard guard(
|
||||
pcloudProducer.stimulusProducerCanceler.s.lock);
|
||||
if (pcloudProducer.stimulusProducerCanceler
|
||||
.isCancellationRequestedUnlocked())
|
||||
{
|
||||
callOriginalCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
callOriginalCallback();
|
||||
|
||||
if (pcloudProducer.attachedStimulusBuffers.size() > 0) {
|
||||
if (attachedStimulusBuffers.size() > 0) {
|
||||
std::cerr << __func__ << ": Failed to assemble frame.\n";
|
||||
}
|
||||
return;
|
||||
co_return;
|
||||
}
|
||||
|
||||
context->frameAssemblyResult = loop;
|
||||
frameAssemblyResult = assembleResult.loop;
|
||||
|
||||
// Check if intensity buffer is attached and acquire frame if so
|
||||
if (auto intensityBuff = pcloudProducer.intensityStimulusBuffer.load(
|
||||
if (auto intensityBuff = intensityStimulusBuffer.load(
|
||||
std::memory_order_acquire))
|
||||
{
|
||||
size_t intensityRingbuffIndex = intensityBuff
|
||||
->ringBuffer.getIndexToProduceInto();
|
||||
|
||||
StimulusFrame& intensityStimFrame = intensityBuff
|
||||
StimulusFrame& intensityStimFrameRef = intensityBuff
|
||||
->ringBuffer.getDataAtSlot(
|
||||
intensityRingbuffIndex);
|
||||
|
||||
intensityStimFrame.lock.writeAcquire();
|
||||
context->intensityStimFrame = std::make_optional(
|
||||
std::ref(intensityStimFrame));
|
||||
intensityStimFrameRef.lock.writeAcquire();
|
||||
intensityStimFrame = std::make_optional(
|
||||
std::ref(intensityStimFrameRef));
|
||||
}
|
||||
else {
|
||||
context->intensityStimFrame = std::nullopt;
|
||||
intensityStimFrame = std::nullopt;
|
||||
}
|
||||
|
||||
// Check if light ambience buffer is attached and acquire frame if so
|
||||
std::optional<AmbienceProductionDesc> lightAmbienceProductionDescDesc;
|
||||
if (auto lightAmbienceBuff =
|
||||
pcloudProducer.lightAmbienceStimulusBuffer.load(
|
||||
lightAmbienceStimulusBuffer.load(
|
||||
std::memory_order_acquire))
|
||||
{
|
||||
size_t lightAmbienceRingbuffIndex = lightAmbienceBuff
|
||||
->ringBuffer.getIndexToProduceInto();
|
||||
|
||||
StimulusFrame& lightAmbienceStimFrame = lightAmbienceBuff
|
||||
StimulusFrame& lightAmbienceStimFrameRef = lightAmbienceBuff
|
||||
->ringBuffer.getDataAtSlot(lightAmbienceRingbuffIndex);
|
||||
|
||||
lightAmbienceStimFrame.lock.writeAcquire();
|
||||
context->lightAmbienceStimFrame = std::make_optional(
|
||||
std::ref(lightAmbienceStimFrame));
|
||||
lightAmbienceStimFrameRef.lock.writeAcquire();
|
||||
lightAmbienceStimFrame = std::make_optional(
|
||||
std::ref(lightAmbienceStimFrameRef));
|
||||
lightAmbienceProductionDescDesc = AmbienceProductionDesc{
|
||||
std::ref(lightAmbienceStimFrame),
|
||||
std::ref(lightAmbienceStimFrameRef),
|
||||
lightAmbienceBuff->passbandCountGtComparator};
|
||||
}
|
||||
else {
|
||||
context->lightAmbienceStimFrame = std::nullopt;
|
||||
lightAmbienceStimFrame = std::nullopt;
|
||||
}
|
||||
|
||||
// Check if dark ambience buffer is attached and acquire frame if so
|
||||
std::optional<AmbienceProductionDesc> darkAmbienceProductionDescDesc;
|
||||
if (auto darkAmbienceBuff =
|
||||
pcloudProducer.darkAmbienceStimulusBuffer.load(
|
||||
darkAmbienceStimulusBuffer.load(
|
||||
std::memory_order_acquire))
|
||||
{
|
||||
size_t darkAmbienceRingbuffIndex = darkAmbienceBuff
|
||||
->ringBuffer.getIndexToProduceInto();
|
||||
|
||||
StimulusFrame& darkAmbienceStimFrame = darkAmbienceBuff
|
||||
StimulusFrame& darkAmbienceStimFrameRef = darkAmbienceBuff
|
||||
->ringBuffer.getDataAtSlot(darkAmbienceRingbuffIndex);
|
||||
|
||||
darkAmbienceStimFrame.lock.writeAcquire();
|
||||
context->darkAmbienceStimFrame = std::make_optional(
|
||||
std::ref(darkAmbienceStimFrame));
|
||||
darkAmbienceStimFrameRef.lock.writeAcquire();
|
||||
darkAmbienceStimFrame = std::make_optional(
|
||||
std::ref(darkAmbienceStimFrameRef));
|
||||
darkAmbienceProductionDescDesc = AmbienceProductionDesc{
|
||||
std::ref(darkAmbienceStimFrame),
|
||||
std::ref(darkAmbienceStimFrameRef),
|
||||
darkAmbienceBuff->passbandCountLtComparator};
|
||||
}
|
||||
else {
|
||||
context->darkAmbienceStimFrame = std::nullopt;
|
||||
darkAmbienceStimFrame = std::nullopt;
|
||||
}
|
||||
|
||||
pcloudProducer.openClCollatingAndMeshingEngine.compactCollateAndMeshFrameReq(
|
||||
loop, stimulusFrame,
|
||||
context->intensityStimFrame,
|
||||
std::move(lightAmbienceProductionDescDesc),
|
||||
std::move(darkAmbienceProductionDescDesc),
|
||||
{context, std::bind(
|
||||
&ProduceFrameReq::produceFrameReq3_compactCollateDone,
|
||||
context.get(), context,
|
||||
std::placeholders::_1, std::placeholders::_2)});
|
||||
}
|
||||
|
||||
void produceFrameReq3_compactCollateDone(
|
||||
[[maybe_unused]] std::shared_ptr<ProduceFrameReq> context,
|
||||
bool success, StimulusFrame& /*stimulusFrame*/)
|
||||
{
|
||||
bool compactCollateSuccess = co_await
|
||||
openClCollatingAndMeshingEngine.compactCollateAndMeshFrameCReq(
|
||||
frameAssemblyResult, stimulusFrame,
|
||||
intensityStimFrame,
|
||||
std::move(lightAmbienceProductionDescDesc),
|
||||
std::move(darkAmbienceProductionDescDesc));
|
||||
|
||||
// produceFrameReq3_compactCollateDone
|
||||
#if SMO_DEBUG_PCLOUD_AMBIENCE_INTRIN
|
||||
uint32_t logLightPassbandCount = 0;
|
||||
uint32_t logDarkPassbandCount = 0;
|
||||
bool logLightAmbience = false;
|
||||
bool logDarkAmbience = false;
|
||||
if (success)
|
||||
if (compactCollateSuccess)
|
||||
{
|
||||
if (context->lightAmbienceStimFrame.has_value())
|
||||
if (lightAmbienceStimFrame.has_value())
|
||||
{
|
||||
logLightPassbandCount = *reinterpret_cast<const uint32_t*>(
|
||||
context->lightAmbienceStimFrame->get().slotDesc.vaddr);
|
||||
lightAmbienceStimFrame->get().slotDesc.vaddr);
|
||||
logLightAmbience = true;
|
||||
}
|
||||
if (context->darkAmbienceStimFrame.has_value())
|
||||
if (darkAmbienceStimFrame.has_value())
|
||||
{
|
||||
logDarkPassbandCount = *reinterpret_cast<const uint32_t*>(
|
||||
context->darkAmbienceStimFrame->get().slotDesc.vaddr);
|
||||
darkAmbienceStimFrame->get().slotDesc.vaddr);
|
||||
logDarkAmbience = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Release intensity frame if it was used
|
||||
if (context->intensityStimFrame.has_value()) {
|
||||
context->intensityStimFrame->get().lock.writeRelease();
|
||||
}
|
||||
// Release ambience frames if they were used
|
||||
if (context->lightAmbienceStimFrame.has_value()) {
|
||||
context->lightAmbienceStimFrame->get().lock.writeRelease();
|
||||
}
|
||||
if (context->darkAmbienceStimFrame.has_value()) {
|
||||
context->darkAmbienceStimFrame->get().lock.writeRelease();
|
||||
}
|
||||
// Release intensity frame if it was used
|
||||
if (intensityStimFrame.has_value()) {
|
||||
intensityStimFrame->get().lock.writeRelease();
|
||||
}
|
||||
// Release ambience frames if they were used
|
||||
if (lightAmbienceStimFrame.has_value()) {
|
||||
lightAmbienceStimFrame->get().lock.writeRelease();
|
||||
}
|
||||
if (darkAmbienceStimFrame.has_value()) {
|
||||
darkAmbienceStimFrame->get().lock.writeRelease();
|
||||
}
|
||||
|
||||
sscl::SpinLock::Guard guard(
|
||||
pcloudProducer.stimulusProducerCanceler.s.lock);
|
||||
if (pcloudProducer.stimulusProducerCanceler
|
||||
.isCancellationRequestedUnlocked())
|
||||
{
|
||||
callOriginalCallback();
|
||||
return;
|
||||
}
|
||||
{
|
||||
sscl::SpinLock::Guard guard(stimulusProducerCanceler.s.lock);
|
||||
if (stimulusProducerCanceler.isCancellationRequestedUnlocked())
|
||||
{ co_return; }
|
||||
|
||||
if (!success) {
|
||||
std::cerr << __func__ << ": Failed to compact and collate frame" << std::endl;
|
||||
if (!compactCollateSuccess) {
|
||||
std::cerr << "produceFrameReq3_compactCollateDone"
|
||||
<< ": Failed to compact and collate frame" << std::endl;
|
||||
} else
|
||||
{
|
||||
guard.unlockPrematurely();
|
||||
if (pcloudProducer.pcloudFrameDumper.isEnabled())
|
||||
if (pcloudFrameDumper.isEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
pcloudProducer.pcloudFrameDumper.dumpProducedFrame(
|
||||
*pcloudProducer.device,
|
||||
pcloudProducer.collationBuffer,
|
||||
context->frameAssemblyResult);
|
||||
pcloudFrameDumper.dumpProducedFrame(
|
||||
*device, collationBuffer,
|
||||
frameAssemblyResult);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -653,7 +641,7 @@ public:
|
||||
if (logLightAmbience)
|
||||
{
|
||||
auto lightBuff =
|
||||
pcloudProducer.lightAmbienceStimulusBuffer.load(
|
||||
lightAmbienceStimulusBuffer.load(
|
||||
std::memory_order_acquire);
|
||||
if (lightBuff)
|
||||
{
|
||||
@@ -687,7 +675,7 @@ public:
|
||||
if (logDarkAmbience)
|
||||
{
|
||||
auto darkBuff =
|
||||
pcloudProducer.darkAmbienceStimulusBuffer.load(
|
||||
darkAmbienceStimulusBuffer.load(
|
||||
std::memory_order_acquire);
|
||||
if (darkBuff)
|
||||
{
|
||||
@@ -728,12 +716,12 @@ public:
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
logNow.time_since_epoch()) % 1000;
|
||||
auto assemblyDuration =
|
||||
pcloudProducer.ioUringAssemblyEngine.getAssemblyDuration();
|
||||
ioUringAssemblyEngine.getAssemblyDuration();
|
||||
auto compactDuration =
|
||||
pcloudProducer.openClCollatingAndMeshingEngine
|
||||
openClCollatingAndMeshingEngine
|
||||
.getCompactKernelDuration();
|
||||
auto collateDuration =
|
||||
pcloudProducer.openClCollatingAndMeshingEngine
|
||||
openClCollatingAndMeshingEngine
|
||||
.getCollateKernelDuration();
|
||||
std::cout << std::put_time(std::localtime(&logTime), "%T")
|
||||
<< '.' << std::setfill('0') << std::setw(3)
|
||||
@@ -745,29 +733,9 @@ public:
|
||||
<< "ms" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
callOriginalCallback();
|
||||
}
|
||||
};
|
||||
|
||||
void PcloudStimulusProducer::produceFrameReq(
|
||||
sscl::cps::Callback<produceFrameReqCbFn> callback)
|
||||
{
|
||||
/** EXPLANATION:
|
||||
* We shouldn't acquire stimulusProducerCanceler.s.lock here because
|
||||
* this function is called from
|
||||
* StimulusProducer::stimFrameProductionTimesliceInd(), which is already
|
||||
* holding the lock.
|
||||
*/
|
||||
auto caller = smoHooksPtr->ComponentThread_getSelf();
|
||||
auto request = std::make_shared<ProduceFrameReq>(
|
||||
*this, caller, std::move(callback));
|
||||
|
||||
// Post the doAssemble method to the component thread
|
||||
boost::asio::post(device->componentThread->getIoContext(),
|
||||
STC(std::bind(
|
||||
&ProduceFrameReq::produceFrameReq1_doAssemble_posted,
|
||||
request.get(), request)));
|
||||
co_return;
|
||||
}
|
||||
|
||||
} // namespace stim_buff
|
||||
|
||||
Reference in New Issue
Block a user