123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- //
- #pragma once
- #include <chrono>
- #include "IODeviceWithSCF.tlh"
- //-----------------------------------------------------------------------------
- // IODeviceWithSCF
- //-----------------------------------------------------------------------------
- namespace DIOS::Dev::Detail
- {
- template <typename T>
- void IODriverWithSCF <T>::Prepare ()
- {
- super::Prepare ();
- assert (m_SCFDllName.length ());
- m_SCF = nsSCF::SCF::FromDLL (m_SCFDllName.c_str ());
- m_SCF.OnPassiveDisconnected = [ this ] ()
- {
- this->EventCenter->OnPassiveDisconnected();
- this->OnNewPacket.Set();
- };
- m_SCF.Queue.OnNewPacket = [ this ] ()
- {
- this->OnNewPacket.Set ();
- };
- }
- template <typename T>
- bool IODriverWithSCF <T>::Connect ()
- {
- auto THReadPacket = [ this ] ()
- {
- auto msWait = std::chrono::milliseconds (m_msWaitSCFTimeOut);
- while (true)
- {
- //mLog::Info("THReadPacket: begin wait");
- auto rc = OnNewPacket.Wait (msWait);
- //mLog::Info("THReadPacket: end wait");
- if (! m_SCF.isConnected ())
- return ;
- if (! rc) continue; // 等待超时
- if (!m_SCF.isConnected ())
- return;
- while (true) // 有数据到达, 全部读完, 然后等待下一个事件
- {
- if (!m_SCF.isConnected ())
- return;
- if (m_SCF.Queue.isEmpty ())
- break;
- char cMsg [CMD_LEN_MAX];
- memset (cMsg, 0, sizeof (cMsg));
- int PacketLength = CMD_LEN_MAX;
- int len = m_SCF.Queue.Dequeue (cMsg, PacketLength, 20);
- if (len > 0)
- Dequeue (cMsg, len);
- }
- }
- };
- auto THFunc = [this, THReadPacket] ()
- {
- THReadPacket ();
- m_TID = decltype (m_TID) (); // ! 记得在这里复位 ThreadID
- };
- int res = true;
- auto TH = std::thread(THFunc);
- if (THREAD_PRIORITY_NORMAL != m_nPriority)
- {
- res = SetThreadPriority(TH.native_handle(), m_nPriority);
- }
- if (m_TID == decltype (m_TID) ())
- {
- m_TID = TH.get_id ();
- TH.detach ();
- }
- m_SCF.DecodePack(isActDecodeFun);
- return res;
- }
- template <typename T>
- void IODriverWithSCF <T>::Disconnect ()
- {
- m_SCF.Disconnect ();
- OnNewPacket.Set ();
- super::Disconnect ();
- }
- template<typename T>
- bool IODriverWithSCF<T>::DecodePack(bool action)
- {
- isActDecodeFun = action;
- return isActDecodeFun;
- }
- template<typename T>
- void IODriverWithSCF<T>::SetThread_Priority(int level)
- {
- // 优先级范围从-2到15,7是默认优先级
- m_nPriority = level;
- }
- // 函数: SetThread_Affinity(const std::vector<int>& cpus)
- // 描述: 设置线程的CPU亲和性
- // 参数: cpus - 要绑定的CPU核心序列
- // 返回值: 无
- template<typename T>
- void IODriverWithSCF<T>::SetThread_Affinity(const std::vector<int>& cpus)
- {
- unsigned int num_cores = std::thread::hardware_concurrency();
- if (num_cores == 0) {
- throw std::runtime_error("Failed to determine the number of available cores.");
- }
- #ifdef _WIN32
- DWORD_PTR mask = 0;
- for (const auto& cpu : cpus) {
- if (cpu < 0 || static_cast<unsigned int>(cpu) >= num_cores) {
- throw std::runtime_error("Invalid core number specified.");
- }
- mask |= (1 << cpu);
- }
- DWORD_PTR result = SetThreadAffinityMask(m_ThreadHandle, mask);
- if (result == 0) {
- throw std::runtime_error("Failed to set thread CPU affinity.");
- }
- #else
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- for (const auto& cpu : cpus) {
- if (cpu < 0 || static_cast<unsigned int>(cpu) >= num_cores) {
- throw std::runtime_error("Invalid core number specified.");
- }
- CPU_SET(cpu, &cpuset);
- }
- int result = pthread_setaffinity_np(m_ThreadHandle, sizeof(cpu_set_t), &cpuset);
- if (result != 0) {
- throw std::runtime_error("Failed to set thread CPU affinity.");
- }
- #endif
- }
- template <typename T>
- bool IODriverWithSCF <T>::isConnected () const
- {
- return m_SCF.isConnected ();
- }
- }
|