SWC-DB  v0.5.12 C++ documentations
SWC-DB© (Super Wide Column Database) - High Performance Scalable Database (https://github.com/kashirin-alex/swc-db)
Resource_CPU.h
Go to the documentation of this file.
1 /*
2  * SWC-DB© Copyright since 2019 Alex Kashirin <kashirin.alex@gmail.com>
3  * License details at <https://github.com/kashirin-alex/swc-db/#license>
4  */
5 
6 
7 #ifndef swcdb_common_sys_Resources_CPU_h
8 #define swcdb_common_sys_Resources_CPU_h
9 
10 
11 #if defined(__MINGW64__) || defined(_WIN32)
12 #include <processthreadsapi.h>
13 #else
14 #include <sys/sysinfo.h>
15 #endif
16 
17 #include <fstream>
18 
19 
20 namespace SWC { namespace System {
21 
22 class CPU {
23  static const uint32_t FAIL_MS = 300;
24  public:
25  typedef CPU* Ptr;
30 
31  SWC_SHOULD_NOT_INLINE
32  CPU(Notifier* a_notifier) noexcept
33  : concurrency(std::thread::hardware_concurrency()),
34  mhz(0), usage(0), threads(0),
35  notifier(a_notifier), ms_intval(10000),
36  stat_chk(0), stat_utime(0), stat_stime(0) {
37  }
38 
39  CPU(const CPU&) = delete;
40  CPU(CPU&&) = delete;
41  CPU& operator=(const CPU&) = delete;
42  CPU& operator=(CPU&&) = delete;
43 
44  SWC_SHOULD_NOT_INLINE
45  uint64_t check(uint64_t ts) noexcept {
46  try {
49  return _check(ts);
50  } catch(...) {
52  return FAIL_MS;
53  }
54  }
55 
56  void print(std::ostream& out) const {
57  out << "Res(cores=" << concurrency
58  << " MHz=" << mhz
59  << " usage=" << usage << "%m"
60  << " threads=" << threads << ')';
61  }
62 
63  private:
64 
65  uint64_t _check(uint64_t ts) {
66  if(!concurrency) {
67  concurrency.store(std::thread::hardware_concurrency());
68  if(!concurrency)
69  return FAIL_MS;
70  }
71  if(stat_chk + ms_intval > ts)
72  return (stat_chk + ms_intval) - ts;
73 
74  try {
75  uint64_t utime = 0, stime = 0, _nthreads = 0;
76 
77  #if defined(__MINGW64__) || defined(_WIN32)
78  FILETIME sysIdle, sysKernel, sysUser;
79  if(!GetSystemTimes(&sysIdle, &sysKernel, &sysUser))
80  return FAIL_MS;
81 
82  ULARGE_INTEGER t;
83  t.HighPart = sysKernel.dwHighDateTime;
84  t.LowPart = sysKernel.dwLowDateTime;
85  stime = t.QuadPart;
86  t.HighPart = sysIdle.dwHighDateTime;
87  t.LowPart = sysIdle.dwLowDateTime;
88  if(stime > t.QuadPart)
89  stime -= t.QuadPart;
90  else
91  stime = 0;
92  t.HighPart = sysUser.dwHighDateTime;
93  t.LowPart = sysUser.dwLowDateTime;
94  utime = t.QuadPart;
95 
96  stime *= 10;
97  utime *= 10;
98 
99  #else
100  std::ifstream buffer("/proc/self/stat");
101  if(!buffer.is_open())
102  return FAIL_MS;
103  std::string str_tmp;
104  uint64_t tmp = 0;
105  buffer >> tmp >> str_tmp >> str_tmp
106  >> tmp >> tmp >> tmp
107  >> tmp >> tmp >> tmp
108  >> tmp >> tmp >> tmp
109  >> tmp >> utime >> stime
110  >> tmp >> tmp >> tmp
111  >> tmp >> _nthreads;
112  buffer.close();
113  #endif
114 
115  threads.store(_nthreads);
116  if(notifier)
117  notifier->cpu_threads(_nthreads);
118 
119  if(!stat_chk) {
120  stat_chk = ts;
121  stat_utime = utime;
122  stat_stime = stime;
123  } else {
124  uint64_t chk = ts;
125  std::swap(stat_chk, chk);
126 
127  #if defined(__MINGW64__) || defined(_WIN32)
128  chk = stat_chk - chk;
129  #else
130  chk = ((stat_chk - chk) * sysconf(_SC_CLK_TCK) * concurrency) / 1000;
131  #endif
132 
133  std::swap(stat_utime, utime);
134  utime = ((stat_utime - utime) * 100000) / chk;
135  std::swap(stat_stime, stime);
136  stime = ((stat_stime - stime) * 100000) / chk;
137  usage.store((usage + utime + stime) / (1 + bool(usage)));
138  if(notifier) {
139  notifier->cpu_user(utime);
140  notifier->cpu_sys(stime);
141  }
142  }
143  } catch(...) {
145  }
146 
147  #if defined(__MINGW64__) || defined(_WIN32)
148  mhz.store(0);
149 
150  #else
151  try {
152  std::ifstream buffer(
153  "/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq");
154  if(buffer.is_open()) {
155  size_t khz = 0;
156  buffer >> khz;
157  buffer.close();
158  if(khz)
159  mhz.store(concurrency * (khz/1000));
160  return ms_intval;
161  }
162  } catch(...) {
164  }
165 
166  try {
167  std::ifstream buffer("/proc/cpuinfo");
168  if(buffer.is_open()) {
169  size_t _mhz = 0;
170  std::string tmp;
171  size_t tmp_speed = 0;
172  do {
173  buffer >> tmp;
174  if(Condition::str_eq(tmp.c_str(), "cpu", 3)) {
175  buffer >> tmp;
176  if(Condition::str_eq(tmp.c_str(), "MHz", 3)) {
177  buffer >> tmp >> tmp_speed;
178  _mhz += tmp_speed;
179  }
180  }
181  } while (!buffer.eof());
182  buffer.close();
183  if(_mhz)
184  mhz.store(_mhz);
185  }
186  } catch(...) {
188  return FAIL_MS;
189  }
190  #endif
191  return ms_intval;
192  }
193 
195  uint64_t ms_intval;
196  uint64_t stat_chk;
197  uint64_t stat_utime;
198  uint64_t stat_stime;
199 
200 };
201 
202 
203 }}
204 
205 
206 #endif // swcdb_common_sys_Resources_CPU_h
SWC::System::Notifier::cpu_sys
virtual void cpu_sys(size_t) noexcept=0
SWC::System::CPU::mhz
Core::Atomic< uint32_t > mhz
Definition: Resource_CPU.h:27
SWC::Core::Atomic< uint32_t >
SWC::System::CPU::stat_chk
uint64_t stat_chk
Definition: Resource_CPU.h:196
SWC::System::Notifier
Definition: Resources.h:22
SWC::System::Notifier::get_cpu_ms_interval
virtual uint64_t get_cpu_ms_interval() const noexcept=0
SWC::Condition::str_eq
bool str_eq(const char *s1, const char *s2) noexcept SWC_ATTRIBS((SWC_ATTRIB_O3))
Definition: Comparators_basic.h:237
SWC::Core::AtomicBase::store
constexpr SWC_CAN_INLINE void store(T v) noexcept
Definition: Atomic.h:37
SWC::System::CPU::ms_intval
uint64_t ms_intval
Definition: Resource_CPU.h:195
SWC::System::CPU
Definition: Resource_CPU.h:22
SWC
The SWC-DB C++ namespace 'SWC'.
Definition: main.cc:12
SWC::System::Notifier::cpu_threads
virtual void cpu_threads(size_t) noexcept=0
SWC::System::CPU::FAIL_MS
static const uint32_t FAIL_MS
Definition: Resource_CPU.h:23
SWC::System::CPU::print
void print(std::ostream &out) const
Definition: Resource_CPU.h:56
SWC::System::CPU::stat_stime
uint64_t stat_stime
Definition: Resource_CPU.h:198
SWC::System::CPU::CPU
SWC_SHOULD_NOT_INLINE CPU(Notifier *a_notifier) noexcept
Definition: Resource_CPU.h:32
SWC::System::CPU::_check
uint64_t _check(uint64_t ts)
Definition: Resource_CPU.h:65
SWC::System::CPU::Ptr
CPU * Ptr
Definition: Resource_CPU.h:25
SWC::System::CPU::threads
Core::Atomic< uint32_t > threads
Definition: Resource_CPU.h:29
SWC::System::CPU::stat_utime
uint64_t stat_utime
Definition: Resource_CPU.h:197
SWC::System::CPU::operator=
CPU & operator=(CPU &&)=delete
SWC::System::CPU::notifier
Notifier * notifier
Definition: Resource_CPU.h:194
SWC::System::Notifier::cpu_user
virtual void cpu_user(size_t) noexcept=0
SWC::System::CPU::CPU
CPU(CPU &&)=delete
SWC::System::CPU::check
SWC_SHOULD_NOT_INLINE uint64_t check(uint64_t ts) noexcept
Definition: Resource_CPU.h:45
SWC::System::CPU::usage
Core::Atomic< uint32_t > usage
Definition: Resource_CPU.h:28
SWC::System::CPU::concurrency
Core::Atomic< uint32_t > concurrency
Definition: Resource_CPU.h:26
SWC_LOG_CURRENT_EXCEPTION
#define SWC_LOG_CURRENT_EXCEPTION(_s_)
Definition: Exception.h:144
SWC::System::CPU::operator=
CPU & operator=(const CPU &)=delete
SWC::System::CPU::CPU
CPU(const CPU &)=delete