/** * @file XNThreadManager.cpp * @author jinchao * @brief 线程管理器类源文件 * @version 1.0 * @date 2024-11-07 * * @copyright Copyright (c) 2024 XN * */ #include "XNThreadManager.h" #include "XNThreadManager_p.h" #include "XNFramework.h" #include "XNTimeManager.h" #include "XNModelManager.h" // 默认构造函数 XNThreadManager::XNThreadManager() : XNBaseFrameObject(new XNThreadManagerPrivate()) { SetUniqueId(3); SetObjectName("XNThreadManager"); } XNThreadManager::~XNThreadManager() { } XNThreadManager::XNThreadManager(PrivateType *p) : XNBaseFrameObject(p) { } // 初始化函数 bool XNThreadManager::Initialize() { T_D(); d->_eRunStatus = RunStatus::NotStart; d->threadList.clear(); d->funList.clear(); LOG_INFO("XNThreadManager Initialize Success!"); d->_status = XNFrameObjectStatus::Initialized; return true; } // 开始控制 void XNThreadManager::Start() { T_D(); // 如果当前状态是未开始状态 if (d->_eRunStatus == RunStatus::NotStart) { // 状态切换为正在运行 d->_eRunStatus = RunStatus::Runing; } } // 停止控制 void XNThreadManager::Abort() { T_D(); // 如果当前状态不是停止状态 if (d->_eRunStatus != RunStatus::Aborted) { // 状态切换为停止 d->_eRunStatus = RunStatus::Aborted; } } // 暂停控制 void XNThreadManager::Pause() { T_D(); // 如果当前是正在运行状态 if (d->_eRunStatus == RunStatus::Runing) { // 状态切换为暂停 d->_eRunStatus = RunStatus::Suspend; } } // 继续控制 void XNThreadManager::Continue() { T_D(); // 如果当前是暂停状态 if (d->_eRunStatus == RunStatus::Suspend) { //TODO 这里需要重新设置一下时间信息,不然启动后会加速运行至设定的时间 // 状态切换为正在运行 d->_eRunStatus = RunStatus::Runing; } } // 获取当前运行状态 RunStatus XNThreadManager::GetStatus() { T_D(); return d->_eRunStatus; } // 添加周期性函数 void XNThreadManager::RegisterFunction(uint32_t id, XNCallBack fun, uint32_t threadID, uint32_t freqGroup, uint32_t RunPos, uint32_t RunPriorty) { T_D(); // 如果周期性函数校验通过 if (IsFunParamRight(id, freqGroup, RunPos)) { // 存储提交的函数 funInfoPtr sFunInfo = std::make_shared(); sFunInfo->fun = fun; sFunInfo->threadID = threadID; sFunInfo->freqGroup = freqGroup; sFunInfo->RunPos = RunPos; sFunInfo->RunPriority = RunPriorty; d->funList[id].push_back(sFunInfo); if (d->threadList.find(threadID) != d->threadList.end()) { d->threadList[threadID]->AddFunction(fun, (FreqLevel)freqGroup, RunPos, RunPriorty); LOG_INFO("Model [ %1] register periodic function success! Run node: %2-%3 Priority: %4", id, freqGroup, RunPos, RunPriorty); } else { LOG_ERROR("0x2172 The thread [ %1 ] does not exist, registration failed!", threadID); } } } // 注册函数校验 bool XNThreadManager::IsFunParamRight(uint32_t id, uint32_t freqGroup, uint32_t RunPos) { // 检查提交的函数是否符合规定 if (freqGroup < 0 || freqGroup > 5) { // 如果频率分组不是0~5 LOG_WARNING("0x2170 The submitted function's run frequency group of Model [ %1 ] is not " "between 0 and 5, registration failed!", id); return false; } else if (RunPos > (1 << freqGroup)) { // 如果运行节点不符合要求 LOG_WARNING("0x2171 The run node submitted for registration by model [ %1 ] exceeds the " "maximum node count for the frequency group, registration failed!", id); return false; } return true; } // 仿真运行前做最后处理 bool XNThreadManager::PrepareForExecute() { T_D(); PERIOD_INFO pinfo; clock_gettime(CLOCK_MONOTONIC, &(pinfo.next_period)); for (auto &thread : d->threadList) { thread.second->SetStartTime(pinfo.next_period); } //设置开始事件 auto framework = GetFramework(); if (framework) { auto timeManager = framework->GetTimeManager(); if (timeManager) { timeManager->SetStartTime(pinfo.next_period); } } // 所有线程初始化 LOG_INFO("XNThreadManager is preparing..."); for (auto &thread : d->threadList) { bool bRet = thread.second->Initialize(); if (!bRet) { LOG_ERROR("Thread [ %1 ] PrepareForExecute Failed!", thread.first); continue; } } d->_status = XNFrameObjectStatus::Ready; LOG_INFO("XNThreadManager is prepared!"); return true; } // 添加线程 uint32_t XNThreadManager::AddThreadPool(std::string name, double freq, uint32_t priority, uint32_t CPUAff) { T_D(); // 创建线程对象 XNThreadPtr thread = std::make_shared(name, freq, priority, CPUAff); thread->SetThreadID(AllocateThreadID()); LOG_INFO("Add Thread Success, Frequency: %1 Hz, Interval: %2 ns.", freq, 1.0e9 / freq); d->threadList[thread->GetThreadID()] = thread; return thread->GetThreadID(); } void XNThreadManager::SimControl(uint32_t objectId, SimControlCmd cmd) { T_D(); if (objectId == 0) { switch (cmd) { case SimControlCmd::Start: Start(); break; case SimControlCmd::Abort: Abort(); break; case SimControlCmd::Continue: Continue(); break; case SimControlCmd::Suspend: Pause(); break; } } for (auto &thread : d->threadList) { thread.second->SimControl(objectId, cmd); } } // 获取线程数量 uint32_t XNThreadManager::GetThreadCount() { T_D(); return d->threadList.size(); } // 分配线程ID uint32_t XNThreadManager::AllocateThreadID() { T_D(); //从5000到9999分配线程ID static uint32_t threadID = 5000; while (d->threadList.find(threadID) != d->threadList.end()) { threadID++; } d->threadList[threadID] = nullptr; return threadID; } void XNThreadManager::SetThreadFreqByID(uint32_t threadID, double freq) { T_D(); d->threadList[threadID]->SetRunFrequecy(freq); } double XNThreadManager::GetThreadFreqByID(uint32_t threadID) { T_D(); return d->threadList[threadID]->GetRunFrequecy(); }