|
26 | 26 | #include <unistd.h>
|
27 | 27 | #include <string>
|
28 | 28 | #include <locale.h>
|
| 29 | +#include <sys/sysctl.h> |
| 30 | +#include <mach/mach.h> |
29 | 31 |
|
30 | 32 | #if SHOW_TIMING
|
31 | 33 | #include <Carbon/Carbon.h>
|
@@ -167,3 +169,42 @@ int procinfo_setup(PROC_MAP& pm) {
|
167 | 169 | setlocale(LC_ALL, old_locale.c_str());
|
168 | 170 | return 0;
|
169 | 171 | }
|
| 172 | + |
| 173 | +// get total user-mode CPU time |
| 174 | +// |
| 175 | +// From usr/include/mach/processor_info.h: |
| 176 | +// struct processor_cpu_load_info { /* number of ticks while running... */ |
| 177 | +// unsigned int cpu_ticks[CPU_STATE_MAX]; /* ... in the given mode */ |
| 178 | +// }; |
| 179 | +// |
| 180 | +double total_cpu_time() { |
| 181 | + static natural_t processorCount = 0; |
| 182 | + processor_cpu_load_info_t cpuLoad; |
| 183 | + mach_msg_type_number_t processorMsgCount; |
| 184 | + static double scale; |
| 185 | + uint64_t totalUserTime = 0; |
| 186 | + |
| 187 | + if (processorCount == 0) { |
| 188 | + long hz = sysconf(_SC_CLK_TCK); |
| 189 | + scale = 1./hz; |
| 190 | + } |
| 191 | + |
| 192 | + kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &processorCount, (processor_info_array_t *)&cpuLoad, &processorMsgCount); |
| 193 | + |
| 194 | + if (err != KERN_SUCCESS) { |
| 195 | + return 0.0; |
| 196 | + } |
| 197 | + |
| 198 | + for (natural_t i = 0; i < processorCount; i++) { |
| 199 | + // Calc user and nice CPU usage, with guards against 32-bit overflow |
| 200 | + // (values are natural_t) |
| 201 | + uint64_t user = 0, nice = 0; |
| 202 | + |
| 203 | + user = cpuLoad[i].cpu_ticks[CPU_STATE_USER]; |
| 204 | + nice = cpuLoad[i].cpu_ticks[CPU_STATE_NICE]; |
| 205 | + |
| 206 | + totalUserTime = totalUserTime + user + nice; |
| 207 | + } |
| 208 | + |
| 209 | + return totalUserTime * scale; |
| 210 | +} |
0 commit comments