IODeviceWithSCF.tli 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //
  2. #pragma once
  3. #include <chrono>
  4. #include "IODeviceWithSCF.tlh"
  5. //-----------------------------------------------------------------------------
  6. // IODeviceWithSCF
  7. //-----------------------------------------------------------------------------
  8. namespace DIOS::Dev::Detail
  9. {
  10. template <typename T>
  11. void IODriverWithSCF <T>::Prepare ()
  12. {
  13. super::Prepare ();
  14. assert (m_SCFDllName.length ());
  15. m_SCF = nsSCF::SCF::FromDLL (m_SCFDllName.c_str ());
  16. m_SCF.OnPassiveDisconnected = [ this ] ()
  17. {
  18. this->EventCenter->OnPassiveDisconnected();
  19. this->OnNewPacket.Set();
  20. };
  21. m_SCF.Queue.OnNewPacket = [ this ] ()
  22. {
  23. this->OnNewPacket.Set ();
  24. };
  25. }
  26. template <typename T>
  27. bool IODriverWithSCF <T>::Connect ()
  28. {
  29. auto THReadPacket = [ this ] ()
  30. {
  31. auto msWait = std::chrono::milliseconds (m_msWaitSCFTimeOut);
  32. while (true)
  33. {
  34. //mLog::Info("THReadPacket: begin wait");
  35. auto rc = OnNewPacket.Wait (msWait);
  36. //mLog::Info("THReadPacket: end wait");
  37. if (! m_SCF.isConnected ())
  38. return ;
  39. if (! rc) continue; // 等待超时
  40. if (!m_SCF.isConnected ())
  41. return;
  42. while (true) // 有数据到达, 全部读完, 然后等待下一个事件
  43. {
  44. if (!m_SCF.isConnected ())
  45. return;
  46. if (m_SCF.Queue.isEmpty ())
  47. break;
  48. char cMsg [CMD_LEN_MAX];
  49. memset (cMsg, 0, sizeof (cMsg));
  50. int PacketLength = CMD_LEN_MAX;
  51. int len = m_SCF.Queue.Dequeue (cMsg, PacketLength, 20);
  52. if (len > 0)
  53. Dequeue (cMsg, len);
  54. }
  55. }
  56. };
  57. auto THFunc = [this, THReadPacket] ()
  58. {
  59. THReadPacket ();
  60. m_TID = decltype (m_TID) (); // ! 记得在这里复位 ThreadID
  61. };
  62. int res = true;
  63. auto TH = std::thread(THFunc);
  64. if (THREAD_PRIORITY_NORMAL != m_nPriority)
  65. {
  66. res = SetThreadPriority(TH.native_handle(), m_nPriority);
  67. }
  68. if (m_TID == decltype (m_TID) ())
  69. {
  70. m_TID = TH.get_id ();
  71. TH.detach ();
  72. }
  73. m_SCF.DecodePack(isActDecodeFun);
  74. return res;
  75. }
  76. template <typename T>
  77. void IODriverWithSCF <T>::Disconnect ()
  78. {
  79. m_SCF.Disconnect ();
  80. OnNewPacket.Set ();
  81. super::Disconnect ();
  82. }
  83. template<typename T>
  84. bool IODriverWithSCF<T>::DecodePack(bool action)
  85. {
  86. isActDecodeFun = action;
  87. return isActDecodeFun;
  88. }
  89. template<typename T>
  90. void IODriverWithSCF<T>::SetThread_Priority(int level)
  91. {
  92. // 优先级范围从-2到15,7是默认优先级
  93. m_nPriority = level;
  94. }
  95. // 函数: SetThread_Affinity(const std::vector<int>& cpus)
  96. // 描述: 设置线程的CPU亲和性
  97. // 参数: cpus - 要绑定的CPU核心序列
  98. // 返回值: 无
  99. template<typename T>
  100. void IODriverWithSCF<T>::SetThread_Affinity(const std::vector<int>& cpus)
  101. {
  102. unsigned int num_cores = std::thread::hardware_concurrency();
  103. if (num_cores == 0) {
  104. throw std::runtime_error("Failed to determine the number of available cores.");
  105. }
  106. #ifdef _WIN32
  107. DWORD_PTR mask = 0;
  108. for (const auto& cpu : cpus) {
  109. if (cpu < 0 || static_cast<unsigned int>(cpu) >= num_cores) {
  110. throw std::runtime_error("Invalid core number specified.");
  111. }
  112. mask |= (1 << cpu);
  113. }
  114. DWORD_PTR result = SetThreadAffinityMask(m_ThreadHandle, mask);
  115. if (result == 0) {
  116. throw std::runtime_error("Failed to set thread CPU affinity.");
  117. }
  118. #else
  119. cpu_set_t cpuset;
  120. CPU_ZERO(&cpuset);
  121. for (const auto& cpu : cpus) {
  122. if (cpu < 0 || static_cast<unsigned int>(cpu) >= num_cores) {
  123. throw std::runtime_error("Invalid core number specified.");
  124. }
  125. CPU_SET(cpu, &cpuset);
  126. }
  127. int result = pthread_setaffinity_np(m_ThreadHandle, sizeof(cpu_set_t), &cpuset);
  128. if (result != 0) {
  129. throw std::runtime_error("Failed to set thread CPU affinity.");
  130. }
  131. #endif
  132. }
  133. template <typename T>
  134. bool IODriverWithSCF <T>::isConnected () const
  135. {
  136. return m_SCF.isConnected ();
  137. }
  138. }