cpu.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <err.h>
  2. #include <stdio.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <sys/param.h> /* MIN, MAX */
  6. #include <sys/sysinfo.h>
  7. #include "cpu.h"
  8. #include "../lib/util.h"
  9. #include "../aslstatus.h"
  10. #include "../components_config.h"
  11. /* clang-format off */
  12. #define CPU_SUM(X) \
  13. (X[CPU_STATE_USER] \
  14. + X[CPU_STATE_NICE] \
  15. + X[CPU_STATE_SYSTEM] \
  16. + X[CPU_STATE_IDLE] \
  17. + X[CPU_STATE_IOWAIT] \
  18. + X[CPU_STATE_IRQ] \
  19. + X[CPU_STATE_SOFTIRQ] \
  20. + X[CPU_STATE_STEAL])
  21. #define CPU_USED(X) \
  22. (X[CPU_STATE_USER] \
  23. + X[CPU_STATE_NICE] \
  24. + X[CPU_STATE_SYSTEM] \
  25. + X[CPU_STATE_IRQ] \
  26. + X[CPU_STATE_SOFTIRQ] \
  27. + X[CPU_STATE_STEAL])
  28. /* clang-format on */
  29. static void cpu_perc_cleanup(void *ptr);
  30. void
  31. cpu_freq(char * out,
  32. const char __unused *_a,
  33. uint32_t __unused _i,
  34. static_data_t * static_data)
  35. {
  36. uintmax_t freq, freq_total = 0;
  37. uint8_t n_procs = get_nprocs_conf();
  38. int * fd = static_data->data;
  39. char buf[JU_STR_SIZE], cpu_number[6];
  40. if (!static_data->cleanup) static_data->cleanup = fd_cleanup;
  41. for (int i = 0; i < n_procs; i++) {
  42. sprintf(cpu_number, "cpu%d", i);
  43. if (!sysfs_fd_or_rewind(fd,
  44. "/sys/devices/system/cpu",
  45. "cpu0",
  46. "cpufreq/scaling_cur_freq"))
  47. ERRRET(out);
  48. if (!eread(*fd, WITH_LEN(buf))) ERRRET(out);
  49. /* in kHz */
  50. if (!esscanf(1, buf, "%ju", &freq)) ERRRET(out);
  51. freq_total += freq;
  52. }
  53. fmt_human(out, (freq_total / n_procs) * 1000);
  54. }
  55. void
  56. cpu_perc(char * out,
  57. const char __unused *_a,
  58. uint32_t __unused _i,
  59. static_data_t * static_data)
  60. {
  61. struct cpu_data_t *data = static_data->data;
  62. char buf[STR_SIZE("cpu ") + JU_STR_SIZE * LEN(data->states)];
  63. __typeof__(*data->states) old_states[LEN(data->states)], sum;
  64. __typeof__(sum) tmp_sum, old_sum;
  65. if (!static_data->cleanup) static_data->cleanup = cpu_perc_cleanup;
  66. memcpy(old_states, data->states, sizeof(data->states));
  67. if (!sysfs_fd_or_rewind(&data->fd, "/", "proc", "stat")) ERRRET(out);
  68. if (!eread(data->fd, WITH_LEN(buf))) ERRRET(out);
  69. /* cpu user nice system idle iowait irq softirq */
  70. if (!esscanf(LEN(data->states),
  71. buf,
  72. "cpu %ju %ju %ju %ju %ju %ju %ju %ju",
  73. &data->states[CPU_STATE_USER],
  74. &data->states[CPU_STATE_NICE],
  75. &data->states[CPU_STATE_SYSTEM],
  76. &data->states[CPU_STATE_IDLE],
  77. &data->states[CPU_STATE_IOWAIT],
  78. &data->states[CPU_STATE_IRQ],
  79. &data->states[CPU_STATE_SOFTIRQ],
  80. &data->states[CPU_STATE_STEAL]))
  81. ERRRET(out);
  82. if (!old_states[CPU_STATE_USER]) ERRRET(out);
  83. #define ABS_DEC(A, B) (MAX((A), (B)) - MIN((A), (B)))
  84. old_sum = CPU_SUM(old_states);
  85. tmp_sum = CPU_SUM(data->states);
  86. sum = ABS_DEC(old_sum, tmp_sum);
  87. if (!sum) ERRRET(out);
  88. old_sum = CPU_USED(old_states);
  89. tmp_sum = CPU_USED(data->states);
  90. bprintf(out,
  91. "%" PRIperc,
  92. (percent_t)(100 * ABS_DEC(old_sum, tmp_sum) / sum));
  93. }
  94. static inline void
  95. cpu_perc_cleanup(void *ptr)
  96. {
  97. eclose(((struct cpu_data_t *)ptr)->fd);
  98. }