Libspinscale: begin splitting it off

This commit is contained in:
2025-12-26 01:18:39 -04:00
parent d5c2b61d4c
commit 45959f9d1c
67 changed files with 776 additions and 615 deletions
+2
View File
@@ -92,6 +92,7 @@ configure_file(
# Include directories
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/libspinscale/include
${CMAKE_CURRENT_SOURCE_DIR}/smocore/include
${CMAKE_CURRENT_BINARY_DIR}/include
)
@@ -177,6 +178,7 @@ if(ENABLE_TESTS)
add_subdirectory(third_party)
endif()
add_subdirectory(compile)
add_subdirectory(libspinscale)
# Add core components
add_subdirectory(smocore)
add_subdirectory(commonLibs)
@@ -8,7 +8,7 @@
#include <boost/system/error_code.hpp>
#include <opts.h>
#include <componentThread.h>
#include <spinLock.h>
#include <spinscale/spinLock.h>
#include <user/stimulusProducer.h>
#include <user/stimulusBuffer.h>
+1 -1
View File
@@ -8,7 +8,7 @@
#include <atomic>
#include <boost/asio/ip/udp.hpp>
#include <user/senseApiDesc.h>
#include <spinLock.h>
#include <spinscale/spinLock.h>
#include "device.h"
namespace livoxProto1 {
+2 -2
View File
@@ -3,8 +3,8 @@
#include <functional>
#include <optional>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <callback.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/callback.h>
#include <user/senseApiDesc.h>
#include "protocol.h"
#include "core.h"
+1 -1
View File
@@ -11,7 +11,7 @@
#include "broadcastListener.h"
#include "udpCommandDemuxer.h"
#include "livoxProto1.h"
#include <callback.h>
#include <spinscale/callback.h>
namespace livoxProto1 {
+2 -2
View File
@@ -17,8 +17,8 @@
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <callback.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/callback.h>
#include "device.h"
#include "protocol.h"
#include "core.h"
+2 -2
View File
@@ -18,8 +18,8 @@
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include "protocol.h"
#include <callback.h>
#include <spinLock.h>
#include <spinscale/callback.h>
#include <spinscale/spinLock.h>
// Custom hash function for std::pair<uint8_t, uint8_t>
namespace std {
+1 -1
View File
@@ -1,6 +1,6 @@
#include <boostAsioLinkageFix.h>
#include <stdexcept>
#include <callback.h>
#include <spinscale/callback.h>
#include <boost/asio/posix/stream_descriptor.hpp>
#include "livoxProto1.h"
#include "device.h"
+1 -1
View File
@@ -6,7 +6,7 @@
#include <string>
#include <cstdint>
#include <functional>
#include <callback.h>
#include <spinscale/callback.h>
#include <boost/asio/posix/stream_descriptor.hpp>
// Forward declarations
+1 -1
View File
@@ -6,7 +6,7 @@
#include <memory>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <componentThread.h>
#include <spinLock.h>
#include <spinscale/spinLock.h>
namespace livoxProto1 {
+1 -1
View File
@@ -9,7 +9,7 @@
#include <vector>
#include <preprocessor.h>
#include <user/deviceAttachmentSpec.h>
#include <callback.h>
#include <spinscale/callback.h>
#define CL_TARGET_OPENCL_VERSION 120
#include <CL/cl.h>
+1 -1
View File
@@ -13,7 +13,7 @@
#include <config.h>
#include <boost/asio/io_service.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <spinLock.h>
#include <spinscale/spinLock.h>
#include "deviceAttachmentSpec.h"
namespace smo {
+45
View File
@@ -0,0 +1,45 @@
add_library(spinscale SHARED
src/qutex.cpp
src/lockerAndInvokerBase.cpp
src/componentThread.cpp
src/component.cpp
)
# Conditionally add qutexAcquisitionHistoryTracker.cpp only when debug locks
# are enabled, since the tracker is only referenced under CONFIG_ENABLE_DEBUG_LOCKS.
if(ENABLE_DEBUG_LOCKS)
target_sources(spinscale PRIVATE src/qutexAcquisitionHistoryTracker.cpp)
endif()
# Ensure Boost uses dynamic linking (project-wide setting should handle this,
# but being explicit here for clarity)
target_compile_definitions(spinscale PRIVATE BOOST_ALL_DYN_LINK)
target_compile_features(spinscale PUBLIC cxx_std_20)
target_include_directories(spinscale PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/smocore/include
${PROJECT_BINARY_DIR}/include
${Boost_INCLUDE_DIRS}
)
# Link against required dependencies for shared library
# Boost::system is PUBLIC because componentThread.h exposes Boost.Asio types
find_package(Threads REQUIRED)
target_link_libraries(spinscale PUBLIC
Threads::Threads
Boost::system
Boost::log
)
# Verify Boost dynamic dependencies after build (only if script exists)
if(EXISTS ${CMAKE_SOURCE_DIR}/cmake/VerifyBoostDynamic.cmake)
add_custom_command(TARGET spinscale POST_BUILD
COMMAND ${CMAKE_COMMAND} -DVERIFY_FILE="$<TARGET_FILE:spinscale>"
-P ${CMAKE_SOURCE_DIR}/cmake/VerifyBoostDynamic.cmake
COMMENT "Verifying Boost dynamic dependencies for spinscale"
)
else()
message(WARNING "VerifyBoostDynamic.cmake not found - cannot verify Boost dependencies for spinscale")
endif()
@@ -5,9 +5,9 @@
#include <memory>
#include <exception>
#include <componentThread.h>
#include <callback.h>
#include <callableTracer.h>
#include <asynchronousContinuationChainLink.h>
#include <spinscale/callback.h>
#include <spinscale/callableTracer.h>
#include <spinscale/asynchronousContinuationChainLink.h>
namespace smo {
@@ -1,12 +1,17 @@
#ifndef CALLABLE_TRACER_H
#define CALLABLE_TRACER_H
#ifndef SPINSCALE_CALLABLE_TRACER_H
#define SPINSCALE_CALLABLE_TRACER_H
#include <config.h>
#include <string>
#include <functional>
#include <iostream>
#include <cstdint>
#include <opts.h>
#include <spinscale/componentThread.h>
// Forward declaration - OptionParser is defined in smocore/include/opts.h
// If you need tracing, include opts.h before including this header
// The code will check for OPTS_H define to see if opts.h has been included
class OptionParser;
namespace smo {
@@ -45,6 +50,10 @@ public:
void operator()()
{
// OptionParser::getOptions() requires opts.h to be included
// Only check traceCallables if opts.h has been included (OPTS_H is defined)
#ifdef CONFIG_DEBUG_TRACE_CALLABLES
#ifdef OPTS_H
if (OptionParser::getOptions().traceCallables)
{
std::cout << "" << __func__ << ": On thread "
@@ -56,6 +65,8 @@ public:
<< ", return addr 1: " << returnAddr1
<< std::endl;
}
#endif
#endif
callable();
}
@@ -135,4 +146,4 @@ private:
#define STC(arg) arg
#endif
#endif // CALLABLE_TRACER_H
#endif // SPINSCALE_CALLABLE_TRACER_H
@@ -1,5 +1,5 @@
#ifndef CALLBACK_H
#define CALLBACK_H
#ifndef SPINSCALE_CALLBACK_H
#define SPINSCALE_CALLBACK_H
#include <memory>
@@ -28,4 +28,4 @@ public:
} // namespace smo
#endif // CALLBACK_H
#endif // SPINSCALE_CALLBACK_H
@@ -4,7 +4,7 @@
#include <config.h>
#include <memory>
#include <functional>
#include <callback.h>
#include <spinscale/callback.h>
namespace smo {
@@ -0,0 +1,170 @@
#ifndef COMPONENT_THREAD_H
#define COMPONENT_THREAD_H
#include <boostAsioLinkageFix.h>
#include <atomic>
#include <thread>
#include <unordered_map>
#include <boost/asio/io_service.hpp>
#include <stdexcept>
#include <queue>
#include <functional>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#include <memory>
#include <spinscale/callback.h>
#include <cstdint>
#include <string>
namespace smo {
class MarionetteThread;
class PuppetThread;
// ThreadId is a generic type - application-specific enums should be defined elsewhere
typedef uint8_t ThreadId;
class ComponentThread
{
protected:
ComponentThread(ThreadId _id)
: id(_id), name(getThreadName(_id)),
work(io_service)
{}
public:
virtual ~ComponentThread() = default;
// getThreadName implementation is provided by application code
static std::string getThreadName(ThreadId id);
void cleanup(void);
boost::asio::io_service& getIoService(void) { return io_service; }
static const std::shared_ptr<ComponentThread> getSelf(void);
static bool tlsInitialized(void);
static std::shared_ptr<MarionetteThread> getMrntt();
typedef void (mainFn)(ComponentThread &self);
// CPU management methods
static int getAvailableCpuCount();
typedef std::function<void()> mindShutdownIndOpCbFn;
// Intentionally doesn't take a callback.
void exceptionInd(const std::shared_ptr<ComponentThread> &faultyThread);
// Intentionally doesn't take a callback.
void userShutdownInd();
public:
ThreadId id;
std::string name;
boost::asio::io_service io_service;
boost::asio::io_service::work work;
std::atomic<bool> keepLooping;
};
class MarionetteThread
: public std::enable_shared_from_this<MarionetteThread>,
public ComponentThread
{
public:
MarionetteThread(ThreadId id = 0)
: ComponentThread(id),
thread(main, std::ref(*this))
{
}
static void main(MarionetteThread& self);
void initializeTls(void);
public:
std::thread thread;
};
class PuppetThread
: public std::enable_shared_from_this<PuppetThread>,
public ComponentThread
{
public:
enum class ThreadOp
{
START,
PAUSE,
RESUME,
EXIT,
JOLT,
N_ITEMS
};
PuppetThread(ThreadId _id)
: ComponentThread(_id),
pinnedCpuId(-1),
pause_work(pause_io_service),
thread(main, std::ref(*this))
{
}
virtual ~PuppetThread() = default;
static void main(PuppetThread& self);
void initializeTls(void);
// Thread management methods
typedef std::function<void()> threadLifetimeMgmtOpCbFn;
void startThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
void exitThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
void pauseThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
void resumeThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
/**
* JOLTs this thread to begin processing after global initialization.
*
* JOLTing is the mechanism that allows threads to enter their main
* event loops and set up TLS vars after all global constructors have
* completed. This prevents race conditions during system startup.
*
* @param selfPtr Shared pointer to this thread (required because TLS
* isn't set up yet, so shared_from_this() can't be used)
* @param callback Callback to invoke when JOLT completes
*/
void joltThreadReq(
const std::shared_ptr<PuppetThread>& selfPtr,
Callback<threadLifetimeMgmtOpCbFn> callback);
// CPU management methods
void pinToCpu(int cpuId);
protected:
/**
* Handle exception - called from main() when an exception occurs.
* Derived classes can override to provide application-specific handling.
*/
virtual void handleException() {}
public:
int pinnedCpuId;
boost::asio::io_service pause_io_service;
boost::asio::io_service::work pause_work;
std::thread thread;
public:
class ThreadLifetimeMgmtOp;
};
namespace mrntt {
extern std::shared_ptr<MarionetteThread> thread;
} // namespace mrntt
} // namespace smo
// Forward declaration for spinscale namespace functions and variables
// Must be after smo namespace so ThreadId is defined
namespace spinscale {
extern smo::ThreadId marionetteThreadId;
void setMarionetteThreadId(smo::ThreadId id);
}
#endif // COMPONENT_THREAD_H
@@ -6,8 +6,8 @@
#include <utility>
#include <memory>
#include <optional>
#include <qutex.h>
#include <lockerAndInvokerBase.h>
#include <spinscale/qutex.h>
#include <spinscale/lockerAndInvokerBase.h>
namespace smo {
@@ -5,8 +5,8 @@
#include <list>
#include <memory>
#include <string>
#include <spinLock.h>
#include <lockerAndInvokerBase.h>
#include <spinscale/spinLock.h>
#include <spinscale/lockerAndInvokerBase.h>
namespace smo {
@@ -8,11 +8,11 @@
#include <iostream>
#include <optional>
#include <componentThread.h>
#include <lockSet.h>
#include <asynchronousContinuation.h>
#include <lockerAndInvokerBase.h>
#include <callback.h>
#include <qutexAcquisitionHistoryTracker.h>
#include <spinscale/lockSet.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/lockerAndInvokerBase.h>
#include <spinscale/callback.h>
#include <spinscale/qutexAcquisitionHistoryTracker.h>
namespace smo {
@@ -1,4 +1,4 @@
#include <component.h>
#include <spinscale/component.h>
#include <marionette/marionette.h>
namespace smo {
+318
View File
@@ -0,0 +1,318 @@
#include <boostAsioLinkageFix.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <pthread.h>
#include <sched.h>
#include <boost/asio/io_service.hpp>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/callback.h>
#include <spinscale/callableTracer.h>
#include <componentThread.h>
#include <marionette/marionette.h>
namespace spinscale {
// Global variable to store the marionette thread ID
// Default value is 0, but should be set by application code via setMarionetteThreadId()
smo::ThreadId marionetteThreadId = 0;
void setMarionetteThreadId(smo::ThreadId id)
{
marionetteThreadId = id;
}
} // namespace spinscale
namespace smo {
thread_local std::shared_ptr<ComponentThread> thisComponentThread;
// Implementation of static method
std::shared_ptr<MarionetteThread> ComponentThread::getMrntt()
{
return mrntt::thread;
}
void MarionetteThread::initializeTls(void)
{
thisComponentThread = shared_from_this();
}
void PuppetThread::initializeTls(void)
{
thisComponentThread = shared_from_this();
}
bool ComponentThread::tlsInitialized(void)
{
return thisComponentThread != nullptr;
}
const std::shared_ptr<ComponentThread> ComponentThread::getSelf(void)
{
if (!thisComponentThread)
{
throw std::runtime_error(std::string(__func__)
+ ": TLS not initialized");
}
return thisComponentThread;
}
class PuppetThread::ThreadLifetimeMgmtOp
: public PostedAsynchronousContinuation<threadLifetimeMgmtOpCbFn>
{
public:
ThreadLifetimeMgmtOp(
const std::shared_ptr<ComponentThread> &caller,
const std::shared_ptr<PuppetThread> &target,
Callback<threadLifetimeMgmtOpCbFn> callback)
: PostedAsynchronousContinuation<threadLifetimeMgmtOpCbFn>(
caller, callback),
target(target)
{}
public:
const std::shared_ptr<PuppetThread> target;
public:
void joltThreadReq1_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"JOLT request."
<< "\n";
target->io_service.stop();
callOriginalCb();
}
void startThreadReq1_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"startThread."
<< "\n";
// Execute private setup sequence here
// This is where each thread would implement its specific initialization
callOriginalCb();
}
void exitThreadReq1_mainQueue_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"exitThread (main queue)." << "\n";
target->cleanup();
target->io_service.stop();
callOriginalCb();
}
void exitThreadReq1_pauseQueue_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"exitThread (pause queue)."<< "\n";
target->cleanup();
target->pause_io_service.stop();
target->io_service.stop();
callOriginalCb();
}
void pauseThreadReq1_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"pauseThread." << "\n";
/* We have to invoke the callback here before moving on because
* our next operation is going to block the thread, so it won't
* have a chance to invoke the callback until it's unblocked.
*/
callOriginalCb();
target->pause_io_service.reset();
target->pause_io_service.run();
}
void resumeThreadReq1_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"resumeThread." << "\n";
target->pause_io_service.stop();
callOriginalCb();
}
};
void ComponentThread::cleanup(void)
{
this->keepLooping = false;
}
void PuppetThread::joltThreadReq(
const std::shared_ptr<PuppetThread>& selfPtr,
Callback<threadLifetimeMgmtOpCbFn> callback)
{
/** EXPLANATION:
* We can't use shared_from_this() here because JOLTing occurs prior to
* TLS being set up.
*
* We also can't use getSelf() as yet for the same reason: getSelf()
* requires TLS to be set up.
*
* To obtain a sh_ptr to the caller, we just supply the mrntt thread since
* JOLT is always invoked by the mrntt thread. The JOLT sequence that the
* CRT main() function invokes on the mrntt thread is special since it
* supplies cmdline args and envp.
*
* To obtain a sh_ptr to the target thread, we use the selfPtr parameter
* passed in by the caller.
*/
if (id == spinscale::marionetteThreadId)
{
throw std::runtime_error(std::string(__func__)
+ ": invoked on mrntt thread");
}
std::shared_ptr<MarionetteThread> mrntt = mrntt::thread;
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
mrntt, selfPtr, callback);
this->getIoService().post(
STC(std::bind(
&ThreadLifetimeMgmtOp::joltThreadReq1_posted,
request.get(), request)));
}
// Thread management method implementations
void PuppetThread::startThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
caller, std::static_pointer_cast<PuppetThread>(shared_from_this()),
callback);
this->getIoService().post(
STC(std::bind(
&ThreadLifetimeMgmtOp::startThreadReq1_posted,
request.get(), request)));
}
void PuppetThread::exitThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
caller, std::static_pointer_cast<PuppetThread>(shared_from_this()),
callback);
this->getIoService().post(
STC(std::bind(
&ThreadLifetimeMgmtOp::exitThreadReq1_mainQueue_posted,
request.get(), request)));
pause_io_service.post(
STC(std::bind(
&ThreadLifetimeMgmtOp::exitThreadReq1_pauseQueue_posted,
request.get(), request)));
}
void PuppetThread::pauseThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
if (id == spinscale::marionetteThreadId)
{
throw std::runtime_error(std::string(__func__)
+ ": invoked on mrntt thread");
}
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
caller, std::static_pointer_cast<PuppetThread>(shared_from_this()),
callback);
this->getIoService().post(
STC(std::bind(
&ThreadLifetimeMgmtOp::pauseThreadReq1_posted,
request.get(), request)));
}
void PuppetThread::resumeThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
if (id == spinscale::marionetteThreadId)
{
throw std::runtime_error(std::string(__func__)
+ ": invoked on mrntt thread");
}
// Post to the pause_io_service to unblock the paused thread
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
caller, std::static_pointer_cast<PuppetThread>(shared_from_this()),
callback);
pause_io_service.post(
STC(std::bind(
&ThreadLifetimeMgmtOp::resumeThreadReq1_posted,
request.get(), request)));
}
// CPU management method implementations
int ComponentThread::getAvailableCpuCount()
{
int cpuCount = sysconf(_SC_NPROCESSORS_ONLN);
if (cpuCount <= 0)
{
throw std::runtime_error(std::string(__func__)
+ ": Failed to determine CPU count");
}
// Check if std::thread::hardware_concurrency() matches sysconf result
unsigned int hwConcurrency = std::thread::hardware_concurrency();
if (hwConcurrency != static_cast<unsigned int>(cpuCount))
{
std::cerr << "Warning: CPU count mismatch - "
"std::thread::hardware_concurrency() = "
<< hwConcurrency << ", sysconf(_SC_NPROCESSORS_ONLN) = "
<< cpuCount << "\n";
}
return cpuCount;
}
void PuppetThread::pinToCpu(int cpuId)
{
if (cpuId < 0)
{
throw std::runtime_error(std::string(__func__)
+ ": Invalid CPU ID: " + std::to_string(cpuId));
}
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpuId, &cpuset);
int result = pthread_setaffinity_np(
thread.native_handle(), sizeof(cpu_set_t), &cpuset);
if (result != 0)
{
throw std::runtime_error(std::string(__func__)
+ ": Failed to pin thread to CPU " + std::to_string(cpuId)
+ ": " + std::strerror(result));
}
pinnedCpuId = cpuId;
}
} // namespace smo
@@ -0,0 +1,5 @@
#include <spinscale/lockerAndInvokerBase.h>
namespace smo {
} // namespace smo
@@ -1,5 +1,5 @@
#include <qutex.h>
#include <lockerAndInvokerBase.h>
#include <spinscale/qutex.h>
#include <spinscale/lockerAndInvokerBase.h>
namespace smo {
@@ -1,7 +1,7 @@
#include "qutexAcquisitionHistoryTracker.h"
#include "serializedAsynchronousContinuation.h"
#include "qutex.h"
#include "dependencyGraph.h"
#include <spinscale/qutexAcquisitionHistoryTracker.h>
#include <spinscale/serializedAsynchronousContinuation.h>
#include <spinscale/qutex.h>
#include <spinscale/dependencyGraph.h>
#include <memory>
#include <forward_list>
#include <functional>
+3 -1
View File
@@ -2,10 +2,12 @@
#include <pthread.h>
#include <componentThread.h>
#include <marionette/marionette.h>
#include <spinscale/componentThread.h>
int main(int argc, char *argv[], char *envp[])
{
// Set the marionette thread ID before using any ComponentThread functionality
spinscale::setMarionetteThreadId(smo::SmoThreadId::MRNTT);
pthread_setname_np(pthread_self(), "smo:CRT:main");
/* We don't do anything inside of main()
* Main merely waits for the marionette thread to exit.
+7 -9
View File
@@ -5,11 +5,9 @@ include(${CMAKE_SOURCE_DIR}/cmake/flexYacc.cmake)
add_library(smocore STATIC
# Core files
mind.cpp
opts.cpp
mindThread.cpp
componentThread.cpp
component.cpp
qutex.cpp
lockerAndInvokerBase.cpp
opts.cpp
# Body
body/body.cpp
@@ -41,11 +39,6 @@ add_library(smocore STATIC
mindManager/mindManager.cpp
)
# Conditionally add qutexAcquisitionHistoryTracker.cpp only when debug locks are enabled
if(ENABLE_DEBUG_LOCKS)
target_sources(smocore PRIVATE qutexAcquisitionHistoryTracker.cpp)
endif()
target_include_directories(smocore PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}
@@ -53,6 +46,11 @@ target_include_directories(smocore PUBLIC
${OPENCL_INCLUDE_DIRS}
)
# smocore public headers expose Qutex and friends
target_link_libraries(smocore PUBLIC
spinscale
)
# Link against pthread for CPU affinity functions
find_package(Threads REQUIRED)
target_link_libraries(smocore PRIVATE
+8 -8
View File
@@ -1,9 +1,9 @@
#include <iostream>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <callableTracer.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/asynchronousLoop.h>
#include <spinscale/callback.h>
#include <spinscale/callableTracer.h>
#include <body/body.h>
#include <componentThread.h>
#include <mind.h>
@@ -38,7 +38,7 @@ public:
)
{
auto self = ComponentThread::getSelf();
if (self->id != ComponentThread::BODY)
if (self->id != SmoThreadId::BODY)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be executed on Body thread");
@@ -113,7 +113,7 @@ public:
)
{
auto self = ComponentThread::getSelf();
if (self->id != ComponentThread::BODY)
if (self->id != SmoThreadId::BODY)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be executed on Body thread");
@@ -149,7 +149,7 @@ void Body::initializeReq(Callback<bodyLifetimeMgmtOpCbFn> callback)
{
auto mrntt = ComponentThread::getSelf();
if (mrntt->id != ComponentThread::MRNTT)
if (mrntt->id != SmoThreadId::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be invoked by Mrntt thread");
@@ -168,7 +168,7 @@ void Body::finalizeReq(Callback<bodyLifetimeMgmtOpCbFn> callback)
{
auto mrntt = ComponentThread::getSelf();
if (mrntt->id != ComponentThread::MRNTT)
if (mrntt->id != SmoThreadId::MRNTT)
{
std::cerr << __func__ << ": Must be invoked by Mrntt thread"
<< std::endl;
+21 -301
View File
@@ -1,66 +1,40 @@
#include <boostAsioLinkageFix.h>
#include <unistd.h>
#include <iostream>
#include <stdexcept>
#include <string>
#include <iostream>
#include <pthread.h>
#include <sched.h>
#include <boost/asio/io_service.hpp>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <callback.h>
#include <callableTracer.h>
#include <mind.h>
#include <mindManager/mindManager.h>
#include <componentThread.h>
#include <marionette/marionette.h>
namespace smo {
thread_local std::shared_ptr<ComponentThread> thisComponentThread;
// Implementation of static method
std::shared_ptr<MarionetteThread> ComponentThread::getMrntt()
std::string ComponentThread::getThreadName(ThreadId id)
{
return mrntt::thread;
}
void MarionetteThread::initializeTls(void)
{
thisComponentThread = shared_from_this();
}
void MindThread::initializeTls(void)
{
thisComponentThread = shared_from_this();
}
bool ComponentThread::tlsInitialized(void)
{
return thisComponentThread != nullptr;
}
const std::shared_ptr<ComponentThread> ComponentThread::getSelf(void)
{
if (!thisComponentThread)
// Cast ThreadId to SmoThreadId for validation and lookup
SmoThreadId smoId = static_cast<SmoThreadId>(id);
if (static_cast<int>(smoId) >= static_cast<int>(SmoThreadId::N_ITEMS))
{
throw std::runtime_error(std::string(__func__)
+ ": TLS not initialized");
+ ": Invalid thread ID");
}
return thisComponentThread;
// Use function-local static to ensure proper initialization order
static const std::string threadNames[static_cast<int>(SmoThreadId::N_ITEMS)]
= {
"mrntt",
"director",
"simulator",
"subconscious",
"body",
"world"
};
return threadNames[static_cast<int>(smoId)];
}
void MindThread::main(MindThread& self)
void PuppetThread::main(PuppetThread& self)
{
std::string threadName = "smo:" + self.name;
pthread_setname_np(pthread_self(), threadName.c_str());
if (OptionParser::getOptions().verbose)
{
std::cout << self.name << ":" << __func__ << ": Waiting for JOLT"
<<"\n";
}
self.getIoService().run();
self.initializeTls();
@@ -106,265 +80,11 @@ void MindThread::main(MindThread& self)
if (sendExceptionInd)
{
mrntt::mrntt.exceptionInd();
self.handleException();
}
}
std::cout << self.name << ":" << __func__ << ": Exited event loop" << "\n";
}
class MindThread::ThreadLifetimeMgmtOp
: public PostedAsynchronousContinuation<threadLifetimeMgmtOpCbFn>
{
public:
ThreadLifetimeMgmtOp(
const std::shared_ptr<ComponentThread> &caller,
const std::shared_ptr<MindThread> &target,
Callback<threadLifetimeMgmtOpCbFn> callback)
: PostedAsynchronousContinuation<threadLifetimeMgmtOpCbFn>(
caller, callback),
target(target)
{}
public:
const std::shared_ptr<MindThread> target;
public:
void joltThreadReq1_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"JOLT request."
<< "\n";
target->io_service.stop();
callOriginalCb();
}
void startThreadReq1_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"startThread."
<< "\n";
// Execute private setup sequence here
// This is where each thread would implement its specific initialization
callOriginalCb();
}
void exitThreadReq1_mainQueue_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"exitThread (main queue)." << "\n";
target->cleanup();
target->io_service.stop();
callOriginalCb();
}
void exitThreadReq1_pauseQueue_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"exitThread (pause queue)."<< "\n";
target->cleanup();
target->pause_io_service.stop();
target->io_service.stop();
callOriginalCb();
}
void pauseThreadReq1_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"pauseThread." << "\n";
/* We have to invoke the callback here before moving on because
* our next operation is going to block the thread, so it won't
* have a chance to invoke the callback until it's unblocked.
*/
callOriginalCb();
target->pause_io_service.reset();
target->pause_io_service.run();
}
void resumeThreadReq1_posted(
[[maybe_unused]] std::shared_ptr<ThreadLifetimeMgmtOp> context
)
{
std::cout << __func__ << ": Thread '" << target->name << "': handling "
"resumeThread." << "\n";
target->pause_io_service.stop();
callOriginalCb();
}
};
void ComponentThread::cleanup(void)
{
this->keepLooping = false;
}
void MindThread::joltThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
/** EXPLANATION:
* We can't use shared_from_this() here because JOLTing occurs prior to
* TLS being set up.
*
* We also can't use getSelf() as yet for the same reason: getSelf()
* requires TLS to be set up.
*
* To obtain a sh_ptr to the caller, we just supply the mrntt thread since
* JOLT is always invoked by the mrntt thread. The JOLT sequence that the
* CRT main() function invokes on the mrntt thread is special since it
* supplies cmdline args and envp.
*
* To obtain a sh_ptr to the target thread, we explicitly look it up in the
* Mind object's collection of component threads.
*/
if (id == ComponentThread::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": invoked on mrntt thread");
}
std::shared_ptr<MarionetteThread> mrntt = mrntt::thread;
std::shared_ptr<MindThread> target = getParent().getComponentThread(id);
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
mrntt, target, callback);
this->getIoService().post(
STC(std::bind(
&ThreadLifetimeMgmtOp::joltThreadReq1_posted,
request.get(), request)));
}
// Thread management method implementations
void MindThread::startThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
caller, shared_from_this(), callback);
this->getIoService().post(
STC(std::bind(
&ThreadLifetimeMgmtOp::startThreadReq1_posted,
request.get(), request)));
}
void MindThread::exitThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
caller, shared_from_this(), callback);
this->getIoService().post(
STC(std::bind(
&ThreadLifetimeMgmtOp::exitThreadReq1_mainQueue_posted,
request.get(), request)));
pause_io_service.post(
STC(std::bind(
&ThreadLifetimeMgmtOp::exitThreadReq1_pauseQueue_posted,
request.get(), request)));
}
void MindThread::pauseThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
if (id == ComponentThread::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": invoked on mrntt thread");
}
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
caller, shared_from_this(), callback);
this->getIoService().post(
STC(std::bind(
&ThreadLifetimeMgmtOp::pauseThreadReq1_posted,
request.get(), request)));
}
void MindThread::resumeThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
{
if (id == ComponentThread::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": invoked on mrntt thread");
}
// Post to the pause_io_service to unblock the paused thread
std::shared_ptr<ComponentThread> caller = getSelf();
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
caller, shared_from_this(), callback);
pause_io_service.post(
STC(std::bind(
&ThreadLifetimeMgmtOp::resumeThreadReq1_posted,
request.get(), request)));
}
// CPU management method implementations
int ComponentThread::getAvailableCpuCount()
{
int cpuCount = sysconf(_SC_NPROCESSORS_ONLN);
if (cpuCount <= 0)
{
throw std::runtime_error(std::string(__func__)
+ ": Failed to determine CPU count");
}
// Check if std::thread::hardware_concurrency() matches sysconf result
unsigned int hwConcurrency = std::thread::hardware_concurrency();
if (hwConcurrency != static_cast<unsigned int>(cpuCount))
{
std::cerr << "Warning: CPU count mismatch - "
"std::thread::hardware_concurrency() = "
<< hwConcurrency << ", sysconf(_SC_NPROCESSORS_ONLN) = "
<< cpuCount << "\n";
}
return cpuCount;
}
void MindThread::pinToCpu(int cpuId)
{
if (cpuId < 0)
{
throw std::runtime_error(std::string(__func__)
+ ": Invalid CPU ID: " + std::to_string(cpuId));
}
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpuId, &cpuset);
int result = pthread_setaffinity_np(
thread.native_handle(), sizeof(cpu_set_t), &cpuset);
if (result != 0)
{
throw std::runtime_error(std::string(__func__)
+ ": Failed to pin thread to CPU " + std::to_string(cpuId)
+ ": " + std::strerror(result));
}
pinnedCpuId = cpuId;
if (OptionParser::getOptions().verbose)
{
std::cout << name << ": Pinned to CPU " << cpuId << "\n";
}
}
} // namespace smo
+6 -6
View File
@@ -6,10 +6,10 @@
#include <sstream>
#include <memory>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <serializedAsynchronousContinuation.h>
#include <callback.h>
#include <callableTracer.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/serializedAsynchronousContinuation.h>
#include <spinscale/callback.h>
#include <spinscale/callableTracer.h>
#include <componentThread.h>
#include <deviceManager/deviceManager.h>
#include <deviceManager/deviceReattacher.h>
@@ -351,7 +351,7 @@ public:
[[maybe_unused]] std::shared_ptr<AttachStimBuffDeviceReq> context
)
{
if (caller->id != ComponentThread::MRNTT)
if (caller->id != SmoThreadId::MRNTT)
{
std::cerr << std::string(__func__)
<< ": executed on non-mrntt thread: "
@@ -421,7 +421,7 @@ public:
[[maybe_unused]] std::shared_ptr<AttachStimBuffDeviceReq> context
)
{
if (caller->id != ComponentThread::MRNTT)
if (caller->id != SmoThreadId::MRNTT)
{
std::cerr << std::string(__func__)
<< ": executed on non-mrntt thread: "
+1 -1
View File
@@ -2,7 +2,7 @@
#include <iostream>
#include <functional>
#include <componentThread.h>
#include <callback.h>
#include <spinscale/callback.h>
#include <deviceManager/deviceReattacher.h>
#include <deviceManager/deviceManager.h>
+2 -2
View File
@@ -1,9 +1,9 @@
#ifndef _BODY_COMPONENT_H
#define _BODY_COMPONENT_H
#include <component.h>
#include <spinscale/component.h>
#include <functional>
#include <callback.h>
#include <spinscale/callback.h>
namespace smo {
+16 -169
View File
@@ -1,178 +1,25 @@
#ifndef COMPONENT_THREAD_H
#define COMPONENT_THREAD_H
#ifndef SMO_COMPONENT_THREAD_H
#define SMO_COMPONENT_THREAD_H
#include <boostAsioLinkageFix.h>
#include <atomic>
#include <thread>
#include <unordered_map>
#include <boost/asio/io_service.hpp>
#include <stdexcept>
#include <queue>
#include <functional>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#include <memory>
#include <callback.h>
#include <string>
// Include the spinscale componentThread.h which provides ComponentThread, PuppetThread, etc.
#include <spinscale/componentThread.h>
namespace smo {
class Mind; // Forward declaration
class MarionetteThread;
class MindThread;
class ComponentThread
// Application-specific thread ID enum
// Using regular enum (not enum class) to allow implicit conversion to ThreadId
enum SmoThreadId : ThreadId
{
public:
enum ThreadId
{
MRNTT = 0,
DIRECTOR,
SIMULATOR,
SUBCONSCIOUS,
BODY,
WORLD,
N_ITEMS
};
protected:
ComponentThread(ThreadId _id)
: id(_id), name(getThreadName(_id)),
work(io_service)
{}
public:
virtual ~ComponentThread() = default;
void cleanup(void);
boost::asio::io_service& getIoService(void) { return io_service; }
static const std::shared_ptr<ComponentThread> getSelf(void);
static bool tlsInitialized(void);
static std::shared_ptr<MarionetteThread> getMrntt();
typedef void (mainFn)(ComponentThread &self);
// CPU management methods
static int getAvailableCpuCount();
typedef std::function<void()> mindShutdownIndOpCbFn;
// Intentionally doesn't take a callback.
void exceptionInd(const std::shared_ptr<ComponentThread> &faultyThread);
// Intentionally doesn't take a callback.
void userShutdownInd();
public:
ThreadId id;
std::string name;
boost::asio::io_service io_service;
boost::asio::io_service::work work;
std::atomic<bool> keepLooping;
static const std::string getThreadName(ThreadId id)
{
if (id < 0 || id >= ComponentThread::N_ITEMS)
{
throw std::runtime_error(std::string(__func__)
+ ": Invalid thread ID");
}
// Use function-local static to ensure proper initialization order
static const std::string threadNames[N_ITEMS] = {
"mrntt",
"director",
"simulator",
"subconscious",
"body",
"world"
};
return threadNames[id];
}
MRNTT = 0,
DIRECTOR,
SIMULATOR,
SUBCONSCIOUS,
BODY,
WORLD,
N_ITEMS
};
class MarionetteThread
: public std::enable_shared_from_this<MarionetteThread>,
public ComponentThread
{
public:
MarionetteThread()
: ComponentThread(MRNTT),
thread(main, std::ref(*this))
{
}
static void main(MarionetteThread& self);
void initializeTls(void);
public:
std::thread thread;
};
class MindThread
: public std::enable_shared_from_this<MindThread>, public ComponentThread
{
public:
enum class ThreadOp
{
START,
PAUSE,
RESUME,
EXIT,
JOLT,
N_ITEMS
};
MindThread(ThreadId _id, Mind& parent)
: ComponentThread(_id),
pinnedCpuId(-1),
pause_work(pause_io_service),
parent(parent),
thread(main, std::ref(*this))
{
}
static void main(MindThread& self);
void initializeTls(void);
Mind& getParent() const { return parent; }
// Thread management methods
typedef std::function<void()> threadLifetimeMgmtOpCbFn;
void startThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
void exitThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
void pauseThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
void resumeThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
/**
* JOLTs this thread to begin processing after global initialization.
*
* JOLTing is the mechanism that allows threads to enter their main
* event loops and set up TLS vars after all global constructors have
* completed. This prevents race conditions during system startup.
*/
void joltThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback);
// CPU management methods
void pinToCpu(int cpuId);
public:
int pinnedCpuId;
boost::asio::io_service pause_io_service;
boost::asio::io_service::work pause_work;
Mind& parent;
std::thread thread;
public:
class ThreadLifetimeMgmtOp;
class MindShutdownIndOp;
};
namespace mrntt {
extern std::shared_ptr<MarionetteThread> thread;
} // namespace mrntt
} // namespace smo
#endif // COMPONENT_THREAD_H
#endif // SMO_COMPONENT_THREAD_H
+1 -1
View File
@@ -7,7 +7,7 @@
#include <sstream>
#include <user/deviceAttachmentSpec.h>
#include <deviceManager/deviceRole.h>
#include <qutex.h>
#include <spinscale/qutex.h>
namespace smo {
namespace device {
@@ -10,12 +10,12 @@
#include <functional>
#include <user/senseApiDesc.h>
#include <user/deviceAttachmentSpec.h>
#include <asynchronousLoop.h>
#include <spinscale/asynchronousLoop.h>
#include <deviceManager/device.h>
#include <deviceManager/deviceRole.h>
#include <deviceManager/deviceReattacher.h>
#include <callback.h>
#include <qutex.h>
#include <spinscale/callback.h>
#include <spinscale/qutex.h>
namespace smo {
namespace device {
@@ -5,7 +5,7 @@
#include <atomic>
#include <memory>
#include <boost/asio/deadline_timer.hpp>
#include <spinLock.h>
#include <spinscale/spinLock.h>
namespace smo {
+1 -1
View File
@@ -2,7 +2,7 @@
#define DIRECTOR_H
#include <config.h>
#include <component.h>
#include <spinscale/component.h>
#include <goal.h>
#include <lruLifo.h>
+1 -1
View File
@@ -4,7 +4,7 @@
#include <cstdint>
#include <atomic>
#include <memory>
#include <component.h>
#include <spinscale/component.h>
namespace smo {
+4 -4
View File
@@ -7,10 +7,11 @@
#include <memory>
#include <unordered_map>
#include <string>
#include <callback.h>
#include <spinscale/callback.h>
#include <component.h>
#include <spinscale/component.h>
#include <componentThread.h>
#include <mindThread.h>
#include <director/director.h>
#include <simulator/simulator.h>
#include <body/body.h>
@@ -28,8 +29,7 @@ public:
void finalizeReq(Callback<mindLifetimeMgmtOpCbFn> callback);
// ComponentThread access methods
std::shared_ptr<MindThread> getComponentThread(
ComponentThread::ThreadId id) const;
std::shared_ptr<MindThread> getComponentThread(ThreadId id) const;
std::shared_ptr<MindThread> getComponentThread(
const std::string& name) const;
// Get all this Mind's component threads.
+32
View File
@@ -0,0 +1,32 @@
#ifndef MIND_THREAD_H
#define MIND_THREAD_H
#include <memory>
#include <componentThread.h>
namespace smo {
class Mind; // Forward declaration
class MindThread
: public PuppetThread
{
public:
MindThread(ThreadId _id, Mind& parent)
: PuppetThread(_id),
parent(parent)
{
}
Mind& getParent() const { return parent; }
protected:
void handleException() override;
public:
Mind& parent;
};
} // namespace smo
#endif // MIND_THREAD_H
+1 -1
View File
@@ -2,7 +2,7 @@
#define SIMULATOR_H
#include <config.h>
#include <component.h>
#include <spinscale/component.h>
#include <simulator/scene.h>
namespace smo {
@@ -8,7 +8,7 @@
#include <dlfcn.h>
#include <functional>
#include <user/senseApiDesc.h>
#include <qutex.h>
#include <spinscale/qutex.h>
namespace smo {
namespace stim_buff {
@@ -7,11 +7,11 @@
#include <string>
#include <optional>
#include <functional>
#include <asynchronousLoop.h>
#include <spinscale/asynchronousLoop.h>
#include <stimBuffApis/stimBuffApiLib.h>
#include <user/deviceAttachmentSpec.h>
#include <callback.h>
#include <qutex.h>
#include <spinscale/callback.h>
#include <spinscale/qutex.h>
namespace smo {
namespace stim_buff {
-5
View File
@@ -1,5 +0,0 @@
#include <lockerAndInvokerBase.h>
namespace smo {
} // namespace smo
+10 -10
View File
@@ -1,9 +1,9 @@
#include <iostream>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <callableTracer.h>
#include <component.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/asynchronousLoop.h>
#include <spinscale/callback.h>
#include <spinscale/callableTracer.h>
#include <spinscale/component.h>
#include <componentThread.h>
#include <deviceManager/deviceManager.h>
#include <mindManager/mindManager.h>
@@ -33,7 +33,7 @@ public:
)
{
auto self = ComponentThread::getSelf();
if (self->id != ComponentThread::MRNTT)
if (self->id != SmoThreadId::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be executed on Marionette thread");
@@ -71,7 +71,7 @@ public:
)
{
auto self = ComponentThread::getSelf();
if (self->id != ComponentThread::MRNTT)
if (self->id != SmoThreadId::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be executed on Marionette thread");
@@ -133,7 +133,7 @@ public:
)
{
auto self = ComponentThread::getSelf();
if (self->id != ComponentThread::MRNTT)
if (self->id != SmoThreadId::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be executed on Marionette thread");
@@ -150,7 +150,7 @@ void MarionetteComponent::initializeReq(
{
auto mrntt = ComponentThread::getSelf();
if (mrntt->id != ComponentThread::MRNTT)
if (mrntt->id != SmoThreadId::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be executed on Marionette thread");
@@ -170,7 +170,7 @@ void MarionetteComponent::finalizeReq(
{
auto mrntt = ComponentThread::getSelf();
if (mrntt->id != ComponentThread::MRNTT)
if (mrntt->id != SmoThreadId::MRNTT)
{
throw std::runtime_error(std::string(__func__)
+ ": Must be executed on Marionette thread");
+1 -1
View File
@@ -7,7 +7,7 @@
#include <opts.h>
#include <typeinfo>
#include <boost/asio/signal_set.hpp>
#include <asynchronousBridge.h>
#include <spinscale/asynchronousBridge.h>
#include <mindManager/mindManager.h>
#include <componentThread.h>
#include <marionette/marionette.h>
+1 -1
View File
@@ -1,5 +1,5 @@
#include <iostream>
#include <component.h>
#include <spinscale/component.h>
#include <nonNeutralQualia.h>
#include <marionette/marionette.h>
+17 -13
View File
@@ -1,11 +1,11 @@
#include <iostream>
#include <opts.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <callableTracer.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/asynchronousLoop.h>
#include <spinscale/callback.h>
#include <spinscale/callableTracer.h>
#include <mind.h>
#include <componentThread.h>
#include <mindThread.h>
#include <director/director.h>
#include <simulator/simulator.h>
#include <stimBuffApis/stimBuffApiManager.h>
@@ -15,12 +15,12 @@ namespace smo {
Mind::Mind(void)
: componentThreads{
std::make_shared<MindThread>(ComponentThread::DIRECTOR, *this),
std::make_shared<MindThread>(ComponentThread::SIMULATOR, *this),
std::make_shared<MindThread>(ComponentThread::SUBCONSCIOUS, *this),
std::make_shared<MindThread>(ComponentThread::BODY, *this)
std::make_shared<MindThread>(SmoThreadId::DIRECTOR, *this),
std::make_shared<MindThread>(SmoThreadId::SIMULATOR, *this),
std::make_shared<MindThread>(SmoThreadId::SUBCONSCIOUS, *this),
std::make_shared<MindThread>(SmoThreadId::BODY, *this)
#ifndef CONFIG_WORLD_USE_BODY_THREAD
, std::make_shared<MindThread>(ComponentThread::WORLD, *this)
, std::make_shared<MindThread>(SmoThreadId::WORLD, *this)
#endif
},
director(*this, componentThreads[0]),
@@ -38,9 +38,9 @@ Mind::Mind(void)
}
std::shared_ptr<MindThread>
Mind::getComponentThread(ComponentThread::ThreadId id) const
Mind::getComponentThread(ThreadId id) const
{
if (id == ComponentThread::MRNTT)
if (id == SmoThreadId::MRNTT)
{
throw std::runtime_error(
std::string(__func__) +
@@ -339,7 +339,11 @@ void Mind::joltAllMindThreadsReq(
for (auto& thread : componentThreads)
{
thread->joltThreadReq(
std::shared_ptr<PuppetThread> puppetThread =
std::static_pointer_cast<PuppetThread>(thread);
thread->joltThreadReq(
puppetThread,
{request, std::bind(
&MindThreadLifetimeMgmtOp::joltAllMindThreadsReq1,
request.get(), request)});
+12
View File
@@ -0,0 +1,12 @@
#include <componentThread.h>
#include <mindThread.h>
#include <marionette/marionette.h>
namespace smo {
void MindThread::handleException()
{
mrntt::mrntt.exceptionInd();
}
} // namespace smo
+4 -4
View File
@@ -5,10 +5,10 @@
#include <stimBuffApis/stimBuffApiManager.h>
#include <stimBuffApis/stimBuffApiLib.h>
#include <opts.h>
#include <asynchronousBridge.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <spinscale/asynchronousBridge.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/asynchronousLoop.h>
#include <spinscale/callback.h>
#include <user/senseApiDesc.h>
#include <mind.h>
#include <deviceManager/deviceManager.h>
@@ -17,12 +17,12 @@
#include <boost/system/error_code.hpp>
#include <livoxProto1/device.h>
#include <livoxProto1/livoxProto1.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <asynchronousBridge.h>
#include <callback.h>
#include <callableTracer.h>
#include <spinLock.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/asynchronousLoop.h>
#include <spinscale/asynchronousBridge.h>
#include <spinscale/callback.h>
#include <spinscale/callableTracer.h>
#include <spinscale/spinLock.h>
#include "ioUringAssemblyEngine.h"
#include "pcloudStimulusProducer.h"
#include "livoxGen1.h"
@@ -16,10 +16,10 @@
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <livoxProto1/device.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <spinLock.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/asynchronousLoop.h>
#include <spinscale/callback.h>
#include <spinscale/spinLock.h>
#include <user/frameAssemblyDesc.h>
#define IOURINGASSM_ENGN_FRAME_ASSEM_TIMEOUT_MS \
+2 -2
View File
@@ -10,11 +10,11 @@
#include <opts.h>
#include <user/senseApiDesc.h>
#include <user/deviceAttachmentSpec.h>
#include <callback.h>
#include <spinscale/callback.h>
#include <livoxProto1/livoxProto1.h>
#include <livoxProto1/device.h>
#include <livoxProto1/protocol.h>
#include <asynchronousContinuation.h>
#include <spinscale/asynchronousContinuation.h>
#include <boost/asio/deadline_timer.hpp>
#include "pcloudStimulusProducer.h"
#include "livoxGen1.h"
@@ -9,10 +9,10 @@
#include <algorithm>
#include <boost/system/error_code.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <asynchronousContinuation.h>
#include <asynchronousBridge.h>
#include <callback.h>
#include <asynchronousLoop.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/asynchronousBridge.h>
#include <spinscale/callback.h>
#include <spinscale/asynchronousLoop.h>
#include <componentThread.h>
#include <user/stimulusFrame.h>
#include <livoxProto1/device.h>
@@ -13,9 +13,9 @@
#include <chrono>
#define CL_TARGET_OPENCL_VERSION 120
#include <CL/cl.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <spinLock.h>
#include <spinscale/asynchronousLoop.h>
#include <spinscale/callback.h>
#include <spinscale/spinLock.h>
#include <user/stimulusFrame.h>
#include <user/stagingBuffer.h>
#include <user/frameAssemblyDesc.h>
@@ -6,7 +6,7 @@
#include <cstddef>
#include <user/spMcRingBuffer.h>
#include <componentThread.h>
#include <asynchronousLoop.h>
#include <spinscale/asynchronousLoop.h>
#include <user/stimulusFrame.h>
#include <user/frameAssemblyDesc.h>
#include <user/pcloudAmbienceStencil.h>
@@ -119,9 +119,9 @@ tempStimulusFrame(
<< device->componentThread->name << std::endl;
#ifndef CONFIG_WORLD_USE_BODY_THREAD
if (smoHooksPtr->ComponentThread_getSelf()->id != ComponentThread::WORLD)
if (smoHooksPtr->ComponentThread_getSelf()->id != SmoThreadId::WORLD)
#else
if (smoHooksPtr->ComponentThread_getSelf()->id != ComponentThread::BODY)
if (smoHooksPtr->ComponentThread_getSelf()->id != SmoThreadId::BODY)
#endif
{
std::string errMsg = std::string(__func__) +
@@ -6,8 +6,8 @@
#include <user/stimulusProducer.h>
#include <user/stimulusFrame.h>
#include <livoxProto1/device.h>
#include <asynchronousContinuation.h>
#include <callback.h>
#include <spinscale/asynchronousContinuation.h>
#include <spinscale/callback.h>
#include <user/stagingBuffer.h>
#include "ioUringAssemblyEngine.h"
#include "openClCollatingAndMeshingEngine.h"
+1 -1
View File
@@ -8,7 +8,7 @@
#include <xcb/xcb.h>
#include <user/senseApiDesc.h>
#include <user/deviceAttachmentSpec.h>
#include <callback.h>
#include <spinscale/callback.h>
#include <xcbXorg/xcbXorg.h>
#include "xcbWindow.h"
+2 -2
View File
@@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include <qutex.h>
#include <lockerAndInvokerBase.h>
#include <spinscale/qutex.h>
#include <spinscale/lockerAndInvokerBase.h>
#include <memory>
#include <thread>
#include <chrono>