plugin_idlejitter.c 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "daemon/common.h"
  3. #define CPU_IDLEJITTER_SLEEP_TIME_MS 20
  4. static void cpuidlejitter_main_cleanup(void *ptr) {
  5. worker_unregister();
  6. struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
  7. static_thread->enabled = NETDATA_MAIN_THREAD_EXITING;
  8. collector_info("cleaning up...");
  9. static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
  10. }
  11. void *cpuidlejitter_main(void *ptr) {
  12. worker_register("IDLEJITTER");
  13. worker_register_job_name(0, "measurements");
  14. netdata_thread_cleanup_push(cpuidlejitter_main_cleanup, ptr);
  15. usec_t sleep_ut = config_get_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS) * USEC_PER_MS;
  16. if(sleep_ut <= 0) {
  17. config_set_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS);
  18. sleep_ut = CPU_IDLEJITTER_SLEEP_TIME_MS * USEC_PER_MS;
  19. }
  20. RRDSET *st = rrdset_create_localhost(
  21. "system"
  22. , "idlejitter"
  23. , NULL
  24. , "idlejitter"
  25. , NULL
  26. , "CPU Idle Jitter"
  27. , "microseconds lost/s"
  28. , "idlejitter.plugin"
  29. , NULL
  30. , NETDATA_CHART_PRIO_SYSTEM_IDLEJITTER
  31. , localhost->rrd_update_every
  32. , RRDSET_TYPE_AREA
  33. );
  34. RRDDIM *rd_min = rrddim_add(st, "min", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  35. RRDDIM *rd_max = rrddim_add(st, "max", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  36. RRDDIM *rd_avg = rrddim_add(st, "average", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  37. usec_t update_every_ut = localhost->rrd_update_every * USEC_PER_SEC;
  38. struct timeval before, after;
  39. while (service_running(SERVICE_COLLECTORS)) {
  40. int iterations = 0;
  41. usec_t error_total = 0,
  42. error_min = 0,
  43. error_max = 0,
  44. elapsed = 0;
  45. while (elapsed < update_every_ut) {
  46. now_monotonic_high_precision_timeval(&before);
  47. worker_is_idle();
  48. sleep_usec(sleep_ut);
  49. worker_is_busy(0);
  50. now_monotonic_high_precision_timeval(&after);
  51. usec_t dt = dt_usec(&after, &before);
  52. elapsed += dt;
  53. usec_t error = dt - sleep_ut;
  54. error_total += error;
  55. if(unlikely(!iterations || error < error_min))
  56. error_min = error;
  57. if(error > error_max)
  58. error_max = error;
  59. iterations++;
  60. }
  61. if(iterations) {
  62. rrddim_set_by_pointer(st, rd_min, error_min);
  63. rrddim_set_by_pointer(st, rd_max, error_max);
  64. rrddim_set_by_pointer(st, rd_avg, error_total / iterations);
  65. rrdset_done(st);
  66. }
  67. }
  68. netdata_thread_cleanup_pop(1);
  69. return NULL;
  70. }