You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
2.6 KiB

  1. #ifndef _GNU_SOURCE
  2. #define _GNU_SOURCE
  3. #endif
  4. #include "cpu.hpp"
  5. #include "ghc/filesystem.hpp"
  6. #include "fmt/core.h"
  7. #include <sched.h>
  8. #include <fstream>
  9. int
  10. CPU::getaffinity(const pthread_t thread_id_,
  11. cpu_set_t *cpuset_)
  12. {
  13. CPU_ZERO(cpuset_);
  14. return sched_getaffinity(thread_id_,
  15. sizeof(cpu_set_t),
  16. cpuset_);
  17. }
  18. int
  19. CPU::setaffinity(const pthread_t thread_id_,
  20. cpu_set_t *cpuset_)
  21. {
  22. return pthread_setaffinity_np(thread_id_,
  23. sizeof(cpu_set_t),
  24. cpuset_);
  25. }
  26. int
  27. CPU::setaffinity(const pthread_t thread_id_,
  28. const int cpu_)
  29. {
  30. cpu_set_t cpuset;
  31. CPU_ZERO(&cpuset);
  32. CPU_SET(cpu_,&cpuset);
  33. return CPU::setaffinity(thread_id_,&cpuset);
  34. }
  35. int
  36. CPU::setaffinity(const pthread_t thread_id_,
  37. const std::set<int> cpus_)
  38. {
  39. cpu_set_t cpuset;
  40. CPU_ZERO(&cpuset);
  41. for(auto const cpu : cpus_)
  42. CPU_SET(cpu,&cpuset);
  43. return CPU::setaffinity(thread_id_,&cpuset);
  44. }
  45. static
  46. ghc::filesystem::path
  47. generate_cpu_core_id_path(const int cpu_id_)
  48. {
  49. const ghc::filesystem::path basepath{"/sys/devices/system/cpu"};
  50. return basepath / fmt::format("cpu{}",cpu_id_) / "topology" / "core_id";
  51. }
  52. int
  53. CPU::count()
  54. {
  55. int rv;
  56. cpu_set_t cpuset;
  57. rv = CPU::getaffinity(0,&cpuset);
  58. if(rv < 0)
  59. return rv;
  60. return CPU_COUNT(&cpuset);
  61. }
  62. CPU::CPUVec
  63. CPU::cpus()
  64. {
  65. cpu_set_t cpuset;
  66. CPU::CPUVec cpuvec;
  67. CPU::getaffinity(0,&cpuset);
  68. for(int i = 0; i < CPU_SETSIZE; i++)
  69. {
  70. if(!CPU_ISSET(i,&cpuset))
  71. continue;
  72. cpuvec.push_back(i);
  73. }
  74. return cpuvec;
  75. }
  76. CPU::CPU2CoreMap
  77. CPU::cpu2core()
  78. {
  79. cpu_set_t cpuset;
  80. CPU::CPU2CoreMap c2c;
  81. CPU::getaffinity(0,&cpuset);
  82. for(int i = 0; i < CPU_SETSIZE; i++)
  83. {
  84. int core_id;
  85. std::ifstream ifs;
  86. ghc::filesystem::path path;
  87. if(!CPU_ISSET(i,&cpuset))
  88. continue;
  89. path = ::generate_cpu_core_id_path(i);
  90. ifs.open(path);
  91. if(!ifs)
  92. break;
  93. ifs >> core_id;
  94. c2c[i] = core_id;
  95. ifs.close();
  96. }
  97. return c2c;
  98. }
  99. CPU::Core2CPUsMap
  100. CPU::core2cpus()
  101. {
  102. cpu_set_t cpuset;
  103. CPU::Core2CPUsMap c2c;
  104. CPU::getaffinity(0,&cpuset);
  105. for(int i = 0; i < CPU_SETSIZE; i++)
  106. {
  107. int core_id;
  108. std::ifstream ifs;
  109. ghc::filesystem::path path;
  110. if(!CPU_ISSET(i,&cpuset))
  111. continue;
  112. path = ::generate_cpu_core_id_path(i);
  113. ifs.open(path);
  114. if(!ifs)
  115. break;
  116. ifs >> core_id;
  117. c2c[core_id].insert(i);
  118. ifs.close();
  119. }
  120. return c2c;
  121. }