XNSim/XNCore_Win/XNThreadManager/XNThreadManager.cpp

237 lines
6.5 KiB
C++
Raw Normal View History

2025-07-19 12:44:06 +08:00
/**
* @file XNThreadManager.cpp
* @author jinchao
* @brief 线
* @version 1.0
* @date 2024-11-07
*
* @copyright Copyright (c) 2024 XN
*
*/
#include "XNThreadManager.h"
#include "XNFramework/XNFramework.h"
#include "XNModelManager/XNModelManager.h"
#include "XNThreadManager_p.h"
#include "XNThreadObject/XNThreadObject.h"
#include "XNTimeManager/XNTimeManager.h"
namespace XNSim {
// 默认构造函数
XNThreadManager::XNThreadManager()
: XNBaseFrameObject(new XNThreadManagerPrivate()) {
SetUniqueId(enumValue(XNCoreObjectID::ThreadManager));
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(XN_UINT32 id, XNCallBack fun,
XN_UINT32 threadID, XN_UINT32 freqGroup,
XN_UINT32 RunPos, XN_UINT32 RunPriorty) {
T_D();
// 如果周期性函数校验通过
if (IsFunParamRight(id, freqGroup, RunPos)) {
// 存储提交的函数
XNFunInfoPtr sFunInfo = std::make_shared<XNFunInfo>();
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);
}
}
}
// 注册函数校验
XN_BOOL XNThreadManager::IsFunParamRight(XN_UINT32 id, XN_UINT32 freqGroup,
XN_UINT32 RunPos) {
// 检查提交的函数是否符合规定
if (freqGroup < 0 || freqGroup > 5) {
// 如果频率分组不是05
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;
}
// 仿真运行前做最后处理
XN_BOOL XNThreadManager::PrepareForExecute() {
T_D();
PERIOD_INFO pinfo;
getCurrentRTTime(&(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) {
XN_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;
}
// 添加线程
XN_UINT32 XNThreadManager::AddThreadPool(XN_STRING name, XN_DOUBLE freq,
XN_UINT32 priority, XN_UINT32 CPUAff) {
T_D();
// 创建线程对象
XNThreadObjectPtr thread =
std::make_shared<XNThreadObject>(name, freq, priority, CPUAff);
thread->SetThreadID(AllocateThreadID());
thread->SetFramework(GetFramework());
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(XN_UINT32 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);
}
}
// 获取线程数量
XN_UINT32 XNThreadManager::GetThreadCount() {
T_D();
return d->_threadList.size();
}
// 分配线程ID
XN_UINT32 XNThreadManager::AllocateThreadID() {
T_D();
// 从5000到9999分配线程ID
static XN_UINT32 threadID = 5000;
while (d->_threadList.find(threadID) != d->_threadList.end()) {
threadID++;
}
d->_threadList[threadID] = nullptr;
return threadID;
}
void XNThreadManager::SetThreadFreqByID(XN_UINT32 threadID, XN_DOUBLE freq) {
T_D();
d->_threadList[threadID]->SetRunFrequecy(freq);
}
XN_DOUBLE XNThreadManager::GetThreadFreqByID(XN_UINT32 threadID) {
T_D();
return d->_threadList[threadID]->GetRunFrequecy();
}
} // namespace XNSim