From ab930a2df3c5587a05baec8e6029ed26e17efd26 Mon Sep 17 00:00:00 2001 From: Hayodea Hekol Date: Wed, 10 Jun 2026 21:16:05 -0400 Subject: [PATCH] Add ComparatorApiManager with SmoCallbacks hooks and startup load. Register comparator types via a dedicated manager and expose lookup/create hooks through SmoCallbacks so stimbuff libs can resolve comparators at load time. Co-authored-by: Cursor --- include/user/senseApiDesc.h | 11 ++ smocore/CMakeLists.txt | 3 + smocore/body/body.cpp | 9 + .../comparatorLibs/comparatorApiManager.cpp | 175 ++++++++++++++++++ .../comparatorLibs/comparatorApiManager.h | 72 +++++++ .../include/comparatorLibs/comparatorLib.h | 64 +++++++ smocore/stimBuffApis/stimBuffApiManager.cpp | 25 ++- 7 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 smocore/comparatorLibs/comparatorApiManager.cpp create mode 100644 smocore/include/comparatorLibs/comparatorApiManager.h create mode 100644 smocore/include/comparatorLibs/comparatorLib.h diff --git a/include/user/senseApiDesc.h b/include/user/senseApiDesc.h index 8b94a30..b309831 100644 --- a/include/user/senseApiDesc.h +++ b/include/user/senseApiDesc.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -137,8 +138,18 @@ struct SmoCallbacks */ void (*ComputeManager_releaseDevice)( std::shared_ptr device); + + std::shared_ptr + (*ComparatorManager_getComparatorType)( + cologex::ComparatorTypeId typeId); + + std::unique_ptr (*Comparator_getNewInstance)( + const std::shared_ptr& + comparatorType); }; +const SmoCallbacks& getSmoCallbacks(); + struct Sal_Mgmt_LibOps { /* When Salmanoff loads a stim buff API lib, it calls this function to initialize diff --git a/smocore/CMakeLists.txt b/smocore/CMakeLists.txt index 7b9904a..31f6bb7 100644 --- a/smocore/CMakeLists.txt +++ b/smocore/CMakeLists.txt @@ -39,6 +39,9 @@ add_library(smocore STATIC # Loadable shared libraries loadableLib/loadableLibraryManager.cpp + # Comparator libs + comparatorLibs/comparatorApiManager.cpp + # ComputeManager computeManager/computeManager.cpp diff --git a/smocore/body/body.cpp b/smocore/body/body.cpp index a583dcb..2a7878f 100644 --- a/smocore/body/body.cpp +++ b/smocore/body/body.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace smo { namespace body { @@ -37,6 +38,10 @@ BodyViralPostingInvoker Body::initializeCReq() */ // Upcast to Mind to access Mind-specific members Mind &mind = static_cast(parent); + + comparator_lib::ComparatorApiManager::getInstance() + .loadComparatorLib("libcomparatorCore.so"); + stim_buff::StimBuffApiManager::getInstance() .loadAllStimBuffApiLibsFromOptions(mind.body.thread); @@ -99,6 +104,10 @@ BodyViralPostingInvoker Body::finalizeCReq() std::cout << "Mrntt: About to unload all stim buff api libs." << "\n"; stim_buff::StimBuffApiManager::getInstance().unloadAllStimBuffApiLibs(); + std::cout << "Mrntt: About to unload all comparator libs." << "\n"; + comparator_lib::ComparatorApiManager::getInstance() + .unloadAllComparatorLibs(); + co_return; } diff --git a/smocore/comparatorLibs/comparatorApiManager.cpp b/smocore/comparatorLibs/comparatorApiManager.cpp new file mode 100644 index 0000000..0b95e44 --- /dev/null +++ b/smocore/comparatorLibs/comparatorApiManager.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace smo { +namespace comparator_lib { + +namespace { + +void registerExportedComparatorTypes( + ComparatorApiManager::Resources& resources, + const cologex::ComparatorLibDesc& libDesc) +{ + for (const auto& exportedType : libDesc.exportedComparatorTypes) + { + const uint64_t packedTypeId = exportedType.typeId.pack(); + if (resources.typeRegistry.contains(packedTypeId)) + { + throw std::runtime_error( + std::string(__func__) + + ": Duplicate comparator type registration for vendorId=0x" + + std::to_string(exportedType.typeId.vendorId) + + " typeId=0x" + + std::to_string(exportedType.typeId.typeId)); + } + + auto registeredType = + std::make_shared( + exportedType); + resources.typeRegistry.emplace(packedTypeId, registeredType); + } +} + +void unregisterExportedComparatorTypes( + ComparatorApiManager::Resources& resources, + const cologex::ComparatorLibDesc& libDesc) +{ + for (const auto& exportedType : libDesc.exportedComparatorTypes) { + resources.typeRegistry.erase(exportedType.typeId.pack()); + } +} + +} // namespace + +ComparatorLib& ComparatorApiManager::loadComparatorLib( + const std::string& libraryPath) +{ + loadable_lib::LoadableLibraryManager& llm = + loadable_lib::LoadableLibraryManager::getInstance(); + + if (getComparatorLib(libraryPath)) + { + throw std::runtime_error( + std::string(__func__) + ": ComparatorLib already loaded: " + + libraryPath); + } + + std::shared_ptr + loadedLibrary = llm.loadSharedLibrary(libraryPath); + + auto descFn = loadable_lib::LoadableLibraryManager::resolveSymbol< + SMO_GET_COMPARATOR_LIB_DESC_FN_TYPEDEF *>( + loadedLibrary->getDlopenHandle(), + SMO_GET_COMPARATOR_LIB_DESC_FN_NAME_STR); + + const stim_buff::SmoCallbacks& callbacks = + stim_buff::getSmoCallbacks(); + const cologex::ComparatorLibDesc& libDesc = descFn(callbacks); + + auto lib = std::make_shared(loadedLibrary, descFn); + lib->setComparatorLibDesc(libDesc); + + registerExportedComparatorTypes(s.rsrc, lib->comparatorLibDesc); + s.rsrc.libs.push_back(lib); + + return *lib; +} + +void ComparatorApiManager::unloadComparatorLib(const std::string& libraryPath) +{ + auto& libs = s.rsrc.libs; + auto it = std::find_if( + libs.begin(), libs.end(), + [&libraryPath](const std::shared_ptr& lib) { + return lib->loadedSharedLibrary->libraryPath == libraryPath; + }); + + if (it == libs.end()) + { + std::cerr << std::string(__func__) + ": Library not found: " + << libraryPath << '\n'; + return; + } + + unregisterExportedComparatorTypes(s.rsrc, (*it)->comparatorLibDesc); + std::shared_ptr + loadedLibrary = (*it)->loadedSharedLibrary; + libs.erase(it); + + loadable_lib::LoadableLibraryManager::getInstance() + .unloadSharedLibrary(loadedLibrary); +} + +void ComparatorApiManager::unloadAllComparatorLibs(void) +{ + auto libs = s.rsrc.libs; + s.rsrc.libs.clear(); + s.rsrc.typeRegistry.clear(); + + for (const auto& lib : libs) + { + loadable_lib::LoadableLibraryManager::getInstance() + .unloadSharedLibrary(lib->loadedSharedLibrary); + } +} + +std::optional> +ComparatorApiManager::getComparatorLib(const std::string& libraryPath) +{ + auto& libs = s.rsrc.libs; + auto it = std::find_if( + libs.begin(), libs.end(), + [&libraryPath](const std::shared_ptr& lib) { + return lib->loadedSharedLibrary->libraryPath == libraryPath; + }); + + if (it != libs.end()) { + return *it; + } + + return std::nullopt; +} + +std::shared_ptr +ComparatorApiManager::getComparatorType(cologex::ComparatorTypeId typeId) +{ + const uint64_t packedTypeId = typeId.pack(); + auto it = s.rsrc.typeRegistry.find(packedTypeId); + if (it == s.rsrc.typeRegistry.end()) { + return {}; + } + + return it->second; +} + +std::unique_ptr ComparatorApiManager::getNewComparatorInstance( + cologex::ComparatorTypeId typeId) +{ + return getNewComparatorInstance(getComparatorType(typeId)); +} + +std::unique_ptr ComparatorApiManager::getNewComparatorInstance( + const std::shared_ptr& comparatorType) +{ + if (!comparatorType) + { + throw std::runtime_error( + std::string(__func__) + ": comparatorType is null"); + } + + if (!comparatorType->getNewInstance) + { + throw std::runtime_error( + std::string(__func__) + ": getNewInstance is null"); + } + + return comparatorType->getNewInstance(); +} + +} // namespace comparator_lib +} // namespace smo diff --git a/smocore/include/comparatorLibs/comparatorApiManager.h b/smocore/include/comparatorLibs/comparatorApiManager.h new file mode 100644 index 0000000..55cc1f6 --- /dev/null +++ b/smocore/include/comparatorLibs/comparatorApiManager.h @@ -0,0 +1,72 @@ +#ifndef COMPARATOR_API_MANAGER_H +#define COMPARATOR_API_MANAGER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace smo { +namespace comparator_lib { + +class ComparatorApiManager +{ +public: + struct Resources + { + std::vector> libs; + std::unordered_map< + uint64_t, std::shared_ptr> + typeRegistry; + }; + + static ComparatorApiManager& getInstance() + { + static ComparatorApiManager instance; + return instance; + } + + ComparatorLib& loadComparatorLib(const std::string& libraryPath); + + void unloadComparatorLib(const std::string& libraryPath); + + void unloadAllComparatorLibs(void); + + std::optional> getComparatorLib( + const std::string& libraryPath); + + std::shared_ptr getComparatorType( + cologex::ComparatorTypeId typeId); + + std::unique_ptr getNewComparatorInstance( + cologex::ComparatorTypeId typeId); + + std::unique_ptr getNewComparatorInstance( + const std::shared_ptr& + comparatorType); + +public: + sscl::SharedResourceGroup s; + +private: + ComparatorApiManager() + : s("ComparatorApiManager") + {} + + ~ComparatorApiManager() = default; + + ComparatorApiManager(const ComparatorApiManager&) = delete; + ComparatorApiManager& operator=(const ComparatorApiManager&) = delete; +}; + +} // namespace comparator_lib +} // namespace smo + +#endif // COMPARATOR_API_MANAGER_H diff --git a/smocore/include/comparatorLibs/comparatorLib.h b/smocore/include/comparatorLibs/comparatorLib.h new file mode 100644 index 0000000..4545cfb --- /dev/null +++ b/smocore/include/comparatorLibs/comparatorLib.h @@ -0,0 +1,64 @@ +#ifndef COMPARATOR_LIB_H +#define COMPARATOR_LIB_H + +#include +#include +#include +#include +#include +#include +#include + +namespace smo { +namespace comparator_lib { + +class ComparatorApiManager; + +class ComparatorLib +{ +private: + friend class ComparatorApiManager; + +public: + ComparatorLib( + std::shared_ptr + _loadedSharedLibrary, + SMO_GET_COMPARATOR_LIB_DESC_FN_TYPEDEF descFn) + : loadedSharedLibrary(std::move(_loadedSharedLibrary)), + SMO_GET_COMPARATOR_LIB_DESC_FN_NAME(descFn), + s("ComparatorLib-" + loadedSharedLibrary->libraryPath) + {} + + void setComparatorLibDesc(const cologex::ComparatorLibDesc &desc) + { + if (!cologex::ComparatorLibDesc::sanityCheck(desc)) + { + throw std::runtime_error( + std::string(__func__) + ": Sanity check failed for comparator " + "library descriptor in library '" + + loadedSharedLibrary->libraryPath + "'"); + } + + comparatorLibDesc = desc; + } + +public: + std::shared_ptr + loadedSharedLibrary; + + std::function + SMO_GET_COMPARATOR_LIB_DESC_FN_NAME; + + cologex::ComparatorLibDesc comparatorLibDesc; + + struct ComparatorLibResources + {}; + + sscl::SharedResourceGroup< + sscl::co::CoQutex, ComparatorLibResources> s; +}; + +} // namespace comparator_lib +} // namespace smo + +#endif // COMPARATOR_LIB_H diff --git a/smocore/stimBuffApis/stimBuffApiManager.cpp b/smocore/stimBuffApis/stimBuffApiManager.cpp index 9d23061..15db801 100644 --- a/smocore/stimBuffApis/stimBuffApiManager.cpp +++ b/smocore/stimBuffApis/stimBuffApiManager.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,20 @@ std::optional searchForLibInSmoSearchPathsHook( .searchForLibInSmoSearchPaths(libraryPath); } +std::shared_ptr +ComparatorManager_getComparatorTypeHook(cologex::ComparatorTypeId typeId) +{ + return comparator_lib::ComparatorApiManager::getInstance() + .getComparatorType(typeId); +} + +std::unique_ptr Comparator_getNewInstanceHook( + const std::shared_ptr& comparatorType) +{ + return comparator_lib::ComparatorApiManager::getInstance() + .getNewComparatorInstance(comparatorType); +} + /* Hooks to be provided to stimBuffApiLibs, enabling them to call into Salmanoff * code. */ @@ -86,7 +101,10 @@ SmoCallbacks smoCallbacks = .ComputeManager_releaseUseHostPtrBuffer = ComputeManager_releaseUseHostPtrBuffer, .ComputeManager_getDevice = ComputeManager_getDevice, - .ComputeManager_releaseDevice = ComputeManager_releaseDevice + .ComputeManager_releaseDevice = ComputeManager_releaseDevice, + .ComparatorManager_getComparatorType = + ComparatorManager_getComparatorTypeHook, + .Comparator_getNewInstance = Comparator_getNewInstanceHook }; /* Static file-scope threading model object for senseApi libraries */ @@ -96,6 +114,11 @@ SmoThreadingModelDesc smoThreadingModelDesc = { } // namespace +const SmoCallbacks& getSmoCallbacks() +{ + return smoCallbacks; +} + StimBuffApiLib& StimBuffApiManager::loadStimBuffApiLib( const std::string& libraryPath, const std::shared_ptr& componentThread)