diff --git a/smocore/body/body.cpp b/smocore/body/body.cpp index 2a7878f..7aebe44 100644 --- a/smocore/body/body.cpp +++ b/smocore/body/body.cpp @@ -27,23 +27,21 @@ BodyViralPostingInvoker Body::initializeCReq() } /** EXPLANATION: - * The ComponentThread instance we pass in here is the one that will be - * used by Senseapi libs to perform device-independent background - * operations. - * For example, liblivoxProto1's BroadcastListener will use this thread - * to listen for UDP broadcast dgrams from Livox devices. + * Comparator libs are loaded before stim buff API libs so comparator + * types are registered before stimbuff libs can resolve them via + * SmoCallbacks during getStimBuffApiDesc. * - * We used to use Marionette, but there's a strong argument for using - * Body instead since it's meant to handle device-management operations. + * SmoThreadingModelDesc is initialized in Mind::initializeCReq before + * body::initializeCReq is entered. */ // Upcast to Mind to access Mind-specific members Mind &mind = static_cast(parent); comparator_lib::ComparatorApiManager::getInstance() - .loadComparatorLib("libcomparatorCore.so"); + .loadAllComparatorApiLibsFromOptions(); stim_buff::StimBuffApiManager::getInstance() - .loadAllStimBuffApiLibsFromOptions(mind.body.thread); + .loadAllStimBuffApiLibsFromOptions(); /** EXPLANATION: * Consider body::initializeCReq to have been called if even one of its diff --git a/smocore/comparatorLibs/comparatorApiManager.cpp b/smocore/comparatorLibs/comparatorApiManager.cpp index baaf9d5..b05ae3e 100644 --- a/smocore/comparatorLibs/comparatorApiManager.cpp +++ b/smocore/comparatorLibs/comparatorApiManager.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -118,6 +119,14 @@ void ComparatorApiManager::unloadAllComparatorLibs(void) } } +void ComparatorApiManager::loadAllComparatorApiLibsFromOptions(void) +{ + const auto& options = OptionParser::getOptions(); + for (const auto& libPath : options.comparatorLibs) { + loadComparatorLib(libPath); + } +} + std::optional> ComparatorApiManager::getComparatorLib(const std::string& libraryPath) { diff --git a/smocore/include/comparatorLibs/comparatorApiManager.h b/smocore/include/comparatorLibs/comparatorApiManager.h index 55cc1f6..616c83d 100644 --- a/smocore/include/comparatorLibs/comparatorApiManager.h +++ b/smocore/include/comparatorLibs/comparatorApiManager.h @@ -39,6 +39,8 @@ public: void unloadAllComparatorLibs(void); + void loadAllComparatorApiLibsFromOptions(void); + std::optional> getComparatorLib( const std::string& libraryPath); diff --git a/smocore/include/marionette/marionette.h b/smocore/include/marionette/marionette.h index e2042d2..eba114d 100644 --- a/smocore/include/marionette/marionette.h +++ b/smocore/include/marionette/marionette.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace sscl { @@ -66,6 +67,12 @@ private: extern std::shared_ptr thread; extern MarionetteComponent mrntt; +extern stim_buff::SmoThreadingModelDesc smoThreadingModelDesc; + +void initializeSmoThreadingModelDesc( + const std::shared_ptr& componentThread); + +const stim_buff::SmoThreadingModelDesc& getSmoThreadingModelDesc(); void marionetteInitializeReqCb(bool success); void marionetteFinalizeReqCb(bool success); diff --git a/smocore/include/opts.h b/smocore/include/opts.h index ace753c..ddf338a 100644 --- a/smocore/include/opts.h +++ b/smocore/include/opts.h @@ -41,6 +41,7 @@ public: std::string argv0; std::vector senseApiLibPath; std::vector senseApiLibs; + std::vector comparatorLibs; std::string dapSpecs; std::vector dapSpecFiles; bool verbose, printUsage, traceCallables; diff --git a/smocore/include/stimBuffApis/stimBuffApiManager.h b/smocore/include/stimBuffApis/stimBuffApiManager.h index a7468e5..0aa890b 100644 --- a/smocore/include/stimBuffApis/stimBuffApiManager.h +++ b/smocore/include/stimBuffApis/stimBuffApiManager.h @@ -35,9 +35,7 @@ public: void finalize(void) {}; - StimBuffApiLib& loadStimBuffApiLib( - const std::string& libraryPath, - const std::shared_ptr& componentThread); + StimBuffApiLib& loadStimBuffApiLib(const std::string& libraryPath); std::optional> findStimBuffApiLibByLibraryPath( const std::string& libraryPath); @@ -46,8 +44,7 @@ public: StimBuffApiLib &getStimBuffApiLibByApiName(const std::string& apiName); void unloadStimBuffApiLib(const std::string& libraryPath); - void loadAllStimBuffApiLibsFromOptions( - const std::shared_ptr& componentThread); + void loadAllStimBuffApiLibsFromOptions(void); void unloadAllStimBuffApiLibs(void); body::BodyViralPostingInvoker initializeStimBuffApiLibCReq( diff --git a/smocore/marionette/main.cpp b/smocore/marionette/main.cpp index 04ae979..3147688 100644 --- a/smocore/marionette/main.cpp +++ b/smocore/marionette/main.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -22,6 +23,36 @@ std::shared_ptr thread = std::make_shared< MarionetteComponent mrntt(thread); +stim_buff::SmoThreadingModelDesc smoThreadingModelDesc = { + .componentThread = nullptr +}; + +void initializeSmoThreadingModelDesc( + const std::shared_ptr& componentThread) +{ + if (!componentThread) + { + throw std::runtime_error( + std::string(__func__) + ": componentThread must be non-null"); + } + + if (smoThreadingModelDesc.componentThread + && smoThreadingModelDesc.componentThread != componentThread) + { + throw std::runtime_error( + std::string(__func__) + + ": SmoThreadingModelDesc already initialized with a different " + "ComponentThread"); + } + + smoThreadingModelDesc.componentThread = componentThread; +} + +const stim_buff::SmoThreadingModelDesc& getSmoThreadingModelDesc() +{ + return smoThreadingModelDesc; +} + void marionetteInitializeReqCb(bool success) { if (success) diff --git a/smocore/mind.cpp b/smocore/mind.cpp index bfabde3..562d2a7 100644 --- a/smocore/mind.cpp +++ b/smocore/mind.cpp @@ -125,6 +125,8 @@ mrntt::MrnttViralNonPostingInvokerT Mind::initializeCReq() co_await startAllPuppetThreadsCReq(); std::cout << "Mrntt: All mind threads started." << "\n"; + mrntt::initializeSmoThreadingModelDesc(body.thread); + co_await body.initializeCReq(); std::cout << "Mrntt: Body component initialized." << "\n"; diff --git a/smocore/opts.cpp b/smocore/opts.cpp index 008e7b2..97d39c0 100644 --- a/smocore/opts.cpp +++ b/smocore/opts.cpp @@ -43,6 +43,9 @@ struct option OptionParser::longOptions[] = { {"api-lib-path", required_argument, 0, 'p'}, {"apipath", required_argument, 0, 'p'}, {"libpath", required_argument, 0, 'p'}, + {"comparator-lib", required_argument, 0, 'c'}, + {"comp-lib", required_argument, 0, 'c'}, + {"complib", required_argument, 0, 'c'}, {"verbose", no_argument, 0, 'v'}, {"trace-callables", no_argument, 0, 't'}, {"call-trace", no_argument, 0, 't'}, @@ -62,7 +65,7 @@ void OptionParser::parseArguments(int argc, char *argv[], char **envp) optind = 1; // Reset optind to 1 before parsing opterr = 0; while ((opt = getopt_long( - argc, argv, "s:d:a:p:vht?", longOptions, &optionIndex)) != -1) + argc, argv, "s:d:a:p:c:vht?", longOptions, &optionIndex)) != -1) { switch (opt) { @@ -92,6 +95,9 @@ void OptionParser::parseArguments(int argc, char *argv[], char **envp) senseApiLibPath.push_back(optarg); break; } + case 'c': + comparatorLibs.push_back(optarg); + break; case 'v': verbose = true; break; @@ -115,6 +121,7 @@ std::string OptionParser::getUsage() const return "Usage: " + argv0 + " [-s|--dapspec|--spec ] " "[-d|--dapfile ] " "[-a|--api-lib|--apilib|--api|--lib ] " + "[-c|--comparator-lib|--comp-lib|--complib ] " "[-p|--api-lib-path|--apipath|--libpath ] " "[-v|--verbose] " "[-t|--trace-callables|--call-trace|--calltrace] " @@ -154,5 +161,11 @@ std::string OptionParser::stringifyOptions(void) const } oss << std::endl; + oss << "Comparator Libraries: "; + for (const auto& lib : comparatorLibs) { + oss << lib << " "; + } + oss << std::endl; + return oss.str(); } diff --git a/smocore/stimBuffApis/stimBuffApiManager.cpp b/smocore/stimBuffApis/stimBuffApiManager.cpp index 4d996c0..1759cfc 100644 --- a/smocore/stimBuffApis/stimBuffApiManager.cpp +++ b/smocore/stimBuffApis/stimBuffApiManager.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -37,11 +36,13 @@ std::shared_ptr ComponentThread_getSelf() return sscl::ComponentThread::getSelf(); } +/* Local static function to wrap OptionParser::getOptions for SmoCallbacks */ OptionParser& OptionParser_getOptions() { return OptionParser::getOptions(); } +/* Local static functions to wrap ComputeManager methods for SmoCallbacks */ std::shared_ptr ComputeManager_createUseHostPtrBuffer( void* hostPtr, size_t size, cl_mem_flags flags) @@ -108,11 +109,6 @@ SmoCallbacks smoCallbacks = .Comparator_getNewInstance = Comparator_getNewInstanceHook }; -/* Static file-scope threading model object for senseApi libraries */ -SmoThreadingModelDesc smoThreadingModelDesc = { - .componentThread = nullptr -}; - } // namespace const SmoCallbacks& getSmoCallbacks() @@ -121,8 +117,7 @@ const SmoCallbacks& getSmoCallbacks() } StimBuffApiLib& StimBuffApiManager::loadStimBuffApiLib( - const std::string& libraryPath, - const std::shared_ptr& componentThread) + const std::string& libraryPath) { loadable_lib::LoadableLibraryManager& llm = loadable_lib::LoadableLibraryManager::getInstance(); @@ -142,12 +137,17 @@ StimBuffApiLib& StimBuffApiManager::loadStimBuffApiLib( loadedLibrary->getDlopenHandle(), SMO_GET_STIM_BUFF_API_DESC_FN_NAME_STR); - if (!smoThreadingModelDesc.componentThread) { - smoThreadingModelDesc.componentThread = componentThread; + const stim_buff::SmoThreadingModelDesc& threadingModel = + mrntt::getSmoThreadingModelDesc(); + if (!threadingModel.componentThread) + { + throw std::runtime_error( + std::string(__func__) + + ": SmoThreadingModelDesc has not been initialized"); } const StimBuffApiDesc& libApiDesc = descFn( - smoCallbacks, smoThreadingModelDesc); + smoCallbacks, threadingModel); auto lib = std::make_shared(loadedLibrary, descFn); lib->setStimBuffApiDesc(libApiDesc); @@ -234,12 +234,11 @@ void StimBuffApiManager::unloadAllStimBuffApiLibs(void) } } -void StimBuffApiManager::loadAllStimBuffApiLibsFromOptions( - const std::shared_ptr& componentThread) +void StimBuffApiManager::loadAllStimBuffApiLibsFromOptions(void) { const auto& options = OptionParser::getOptions(); for (const auto& libPath : options.senseApiLibs) { - loadStimBuffApiLib(libPath, componentThread); + loadStimBuffApiLib(libPath); } }