diff --git a/include/user/senseApiDesc.h b/include/user/senseApiDesc.h index f3bd864..8b94a30 100644 --- a/include/user/senseApiDesc.h +++ b/include/user/senseApiDesc.h @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include #define CL_TARGET_OPENCL_VERSION 120 #include @@ -41,8 +43,9 @@ struct SmoThreadingModelDesc * SMO will usually pass in the Marionette thread here. * * State management that's tied to a particular attachment spec should be - * done on the ComponentThread for the thread that SMO provided in the - * attachDeviceCReq call. + * done on the ComponentThread passed to attachDeviceCReq. The attach and + * detach coroutines run on the thread named by ExplicitPostTarget (post-TO); + * SMO orchestration stays on the marionette thread. */ std::shared_ptr componentThread; }; @@ -55,10 +58,14 @@ struct StimBuffDeviceOpResult using sal_mlo_initializeCIndFn = sscl::co::ViralNonPostingInvoker(void); using sal_mlo_finalizeCIndFn = sscl::co::ViralNonPostingInvoker(void); -using sal_mlo_attachDeviceCReqFn = sscl::co::ViralNonPostingInvoker( +using sal_mlo_attachDeviceCReqFn = + sscl::co::DynamicViralPostingInvoker( + sscl::co::ExplicitPostTarget postTarget, const std::shared_ptr& desc, const std::shared_ptr& componentThread); -using sal_mlo_detachDeviceCReqFn = sscl::co::ViralNonPostingInvoker( +using sal_mlo_detachDeviceCReqFn = + sscl::co::DynamicViralPostingInvoker( + sscl::co::ExplicitPostTarget postTarget, const std::shared_ptr& desc); /** diff --git a/libspinscale b/libspinscale index a53e0ca..c608548 160000 --- a/libspinscale +++ b/libspinscale @@ -1 +1 @@ -Subproject commit a53e0ca32547b07bdcd0bd1e9762ac18c4c0347c +Subproject commit c60854845d5650953c2dc591a76142af93349a03 diff --git a/smocore/deviceManager/deviceManager.cpp b/smocore/deviceManager/deviceManager.cpp index 3a4db37..ec35557 100644 --- a/smocore/deviceManager/deviceManager.cpp +++ b/smocore/deviceManager/deviceManager.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include namespace smo { @@ -32,6 +33,16 @@ void assertMarionetteThread() } } +std::shared_ptr threadForDeviceOp( + const DeviceAttachmentSpec& spec) +{ + if (spec.sensorType == 'e') { + return mind::globalMind->world.thread; + } + + return mind::globalMind->body.thread; +} + } // namespace DeviceManager::~DeviceManager() @@ -87,29 +98,30 @@ DeviceManager::attachStimBuffDeviceCReq( co_await lib.s.lock.getAcquireInvocationAndSuspensionPolicy(); sbamGuard.release(); - /** EXPLANATION: - * We pass in either the body or world thread here, depending on whether - * the device is an introspector (idev) or extrospector (edev). - * - * Introspectors are attached to the body thread; extrospectors are - * attached to the world thread. - */ - std::shared_ptr threadForAttachment; + /** EXPLANATION: + * We pass in either the body or world thread here, depending on whether + * the device is an introspector (idev) or extrospector (edev). + * + * Introspectors are attached to the body thread; extrospectors are + * attached to the world thread. + */ + std::shared_ptr targetThread = + threadForDeviceOp(*spec); + if (spec->sensorType == 'e') { - threadForAttachment = mind::globalMind->world.thread; std::cout << __func__ << ": Attaching edev " << spec->deviceIdentifier << " to world thread" << "\n"; } else { - threadForAttachment = mind::globalMind->body.thread; std::cout << __func__ << ": Attaching non-edev " << spec->deviceIdentifier << " to body thread" << "\n"; } co_return co_await lib.stimBuffApiDesc.sal_mgmt_libOps.attachDeviceCReq( - spec, threadForAttachment); + sscl::co::ExplicitPostTarget{targetThread->getIoContext()}, + spec, targetThread); } mrntt::MrnttViralPostingInvoker @@ -150,7 +162,11 @@ DeviceManager::detachStimBuffDeviceCReq( co_await lib.s.lock.getAcquireInvocationAndSuspensionPolicy(); sbamGuard.release(); + std::shared_ptr targetThread = + threadForDeviceOp(*spec); + co_return co_await lib.stimBuffApiDesc.sal_mgmt_libOps.detachDeviceCReq( + sscl::co::ExplicitPostTarget{targetThread->getIoContext()}, spec); } diff --git a/stimBuffApis/livoxGen1/livoxGen1.cpp b/stimBuffApis/livoxGen1/livoxGen1.cpp index 814cf2d..ea472ba 100644 --- a/stimBuffApis/livoxGen1/livoxGen1.cpp +++ b/stimBuffApis/livoxGen1/livoxGen1.cpp @@ -452,11 +452,13 @@ attachByCreatingProducer( } // namespace -sscl::co::ViralNonPostingInvoker +sscl::co::DynamicViralPostingInvoker livoxGen1_attachDeviceCReq( + [[maybe_unused]] sscl::co::ExplicitPostTarget postTarget, const std::shared_ptr &desc, const std::shared_ptr &componentThread) { + (void)postTarget; if (!livoxProto1.livoxProto1_getOrCreateDeviceCReq) { throw std::runtime_error( @@ -482,10 +484,12 @@ livoxGen1_attachDeviceCReq( co_return co_await attachByCreatingProducer(desc, componentThread); } -sscl::co::ViralNonPostingInvoker +sscl::co::DynamicViralPostingInvoker livoxGen1_detachDeviceCReq( + [[maybe_unused]] sscl::co::ExplicitPostTarget postTarget, const std::shared_ptr &desc) { + (void)postTarget; // Case 1: Check if StimBuffer doesn't exist (early return) auto stimProducerBase = getStimulusProducer(desc); if (!stimProducerBase) { diff --git a/stimBuffApis/livoxGen1/livoxGen1Internal.h b/stimBuffApis/livoxGen1/livoxGen1Internal.h index 19030fd..6930aba 100644 --- a/stimBuffApis/livoxGen1/livoxGen1Internal.h +++ b/stimBuffApis/livoxGen1/livoxGen1Internal.h @@ -46,10 +46,16 @@ bool ensureStimBufferAttachedWithoutDuplicates( sscl::co::ViralNonPostingInvoker livoxGen1_initializeCInd(); sscl::co::ViralNonPostingInvoker livoxGen1_finalizeCInd(); -sscl::co::ViralNonPostingInvoker livoxGen1_attachDeviceCReq( + +sscl::co::DynamicViralPostingInvoker +livoxGen1_attachDeviceCReq( + sscl::co::ExplicitPostTarget postTarget, const std::shared_ptr &desc, const std::shared_ptr &componentThread); -sscl::co::ViralNonPostingInvoker livoxGen1_detachDeviceCReq( + +sscl::co::DynamicViralPostingInvoker +livoxGen1_detachDeviceCReq( + sscl::co::ExplicitPostTarget postTarget, const std::shared_ptr &desc); } // namespace smo::stim_buff diff --git a/stimBuffApis/xcbWindow/xcbWindow.cpp b/stimBuffApis/xcbWindow/xcbWindow.cpp index 892a0ef..707e147 100644 --- a/stimBuffApis/xcbWindow/xcbWindow.cpp +++ b/stimBuffApis/xcbWindow/xcbWindow.cpp @@ -274,13 +274,15 @@ static sscl::co::ViralNonPostingInvoker xcbWindow_finalizeCInd(void) co_return 0; } -static sscl::co::ViralNonPostingInvoker +static sscl::co::DynamicViralPostingInvoker xcbWindow_attachDeviceCReq( - const std::shared_ptr& desc, + [[maybe_unused]] sscl::co::ExplicitPostTarget postTarget, + const std::shared_ptr& desc, const std::shared_ptr& componentThread) { + (void)postTarget; // Not used yet, but may be used later. - (void)componentThread; + (void)componentThread; try { g_attachedWindows.emplace_back( @@ -298,10 +300,12 @@ xcbWindow_attachDeviceCReq( co_return smo::stim_buff::StimBuffDeviceOpResult{true, desc}; } -static sscl::co::ViralNonPostingInvoker +static sscl::co::DynamicViralPostingInvoker xcbWindow_detachDeviceCReq( - const std::shared_ptr& spec) + [[maybe_unused]] sscl::co::ExplicitPostTarget postTarget, + const std::shared_ptr& spec) { + (void)postTarget; auto it = std::find_if(g_attachedWindows.begin(), g_attachedWindows.end(), [&spec](const std::unique_ptr& window) { return window->getDeviceAttachmentSpec() == spec;