91ccd16b33
This makes the initialization sequence much cleaner and conceptually well encapsulated. We also now dynamically allocate the Mind objects. They're allocated dynamically by Mrntt inside of initializeReq. This means that we no longer have to worry about jolting and cleaning up the running threads of global mind object even when we never explicitly called Mind.initializeReq. Along with other conceptual improvements to our abstractions, this patch also gets us to a real "end of program initialization" point for the first time.
94 lines
2.9 KiB
C++
94 lines
2.9 KiB
C++
#ifndef _MIND_H
|
|
#define _MIND_H
|
|
|
|
#include <config.h>
|
|
#include <thread>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <string>
|
|
|
|
#include <component.h>
|
|
#include <componentThread.h>
|
|
#include <director/director.h>
|
|
#include <simulator/simulator.h>
|
|
#include <body/body.h>
|
|
|
|
namespace smo {
|
|
|
|
class Mind : public std::enable_shared_from_this<Mind>
|
|
{
|
|
public:
|
|
Mind(void);
|
|
~Mind(void) = default;
|
|
|
|
typedef std::function<void(bool)> mindLifetimeMgmtOpCbFn;
|
|
void initializeReq(mindLifetimeMgmtOpCbFn callback);
|
|
void finalizeReq(mindLifetimeMgmtOpCbFn callback);
|
|
|
|
// ComponentThread access methods
|
|
std::shared_ptr<MindThread> getComponentThread(
|
|
ComponentThread::ThreadId id) const;
|
|
std::shared_ptr<MindThread> getComponentThread(
|
|
const std::string& name) const;
|
|
// Get all this Mind's component threads.
|
|
std::vector<std::shared_ptr<MindThread>> getMindThreads() const;
|
|
|
|
// Thread management methods (moved from ComponentThread)
|
|
typedef std::function<void()> mindThreadLifetimeMgmtOpCbFn;
|
|
void joltAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
|
|
void startAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
|
|
void pauseAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
|
|
void resumeAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
|
|
void exitAllMindThreadsReq(mindThreadLifetimeMgmtOpCbFn callback);
|
|
|
|
// CPU distribution method
|
|
void distributeAndPinThreadsAcrossCpus();
|
|
|
|
private:
|
|
// Collection of ComponentThread instances (excluding marionette)
|
|
std::vector<std::shared_ptr<MindThread>> componentThreads;
|
|
|
|
public:
|
|
director::Director director;
|
|
simulator::Simulator canvas;
|
|
MindComponent subconscious;
|
|
body::Body body;
|
|
MindComponent world;
|
|
|
|
private:
|
|
friend class body::Body;
|
|
/**
|
|
* Indicates whether all mind threads have been JOLTed at least once.
|
|
*
|
|
* JOLTing serves two critical purposes:
|
|
*
|
|
* 1. **Global Constructor Sequencing**: Since pthreads begin executing while
|
|
* global constructors are still being executed, globally defined pthreads
|
|
* cannot depend on global objects having been constructed. JOLTing is done
|
|
* by the CRT's main thread within main(), which provides a sequencing
|
|
* guarantee that global constructors have been called.
|
|
*
|
|
* 2. **shared_from_this Safety**: shared_from_this() requires a prior
|
|
* shared_ptr handle to be established. The global list of
|
|
* shared_ptr<ComponentThread> guarantees that at least one shared_ptr to
|
|
* each ComponentThread has been initialized before JOLTing occurs.
|
|
*
|
|
* This flag ensures that JOLTing happens exactly once and provides
|
|
* a synchronization point for the entire system initialization.
|
|
*/
|
|
bool threadsHaveBeenJolted = false,
|
|
bodyComponentInitialized = false;
|
|
|
|
private:
|
|
class MindLifetimeMgmtOp;
|
|
class MindThreadLifetimeMgmtOp;
|
|
};
|
|
|
|
// Global Mind instance will be defined in marionette.cpp
|
|
extern std::shared_ptr<Mind> globalMind;
|
|
|
|
} // namespace smo
|
|
|
|
#endif
|