plugin_idlejitter.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. 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. unsigned long long counter;
  40. for(counter = 0; 1 ;counter++) {
  41. int iterations = 0;
  42. usec_t error_total = 0,
  43. error_min = 0,
  44. error_max = 0,
  45. elapsed = 0;
  46. if(netdata_exit) break;
  47. while(elapsed < update_every_ut) {
  48. now_monotonic_high_precision_timeval(&before);
  49. worker_is_idle();
  50. sleep_usec(sleep_ut);
  51. worker_is_busy(0);
  52. now_monotonic_high_precision_timeval(&after);
  53. usec_t dt = dt_usec(&after, &before);
  54. elapsed += dt;
  55. usec_t error = dt - sleep_ut;
  56. error_total += error;
  57. if(unlikely(!iterations))
  58. error_min = error;
  59. else if(error < error_min)
  60. error_min = error;
  61. if(error > error_max)
  62. error_max = error;
  63. iterations++;
  64. }
  65. if(netdata_exit) break;
  66. if(iterations) {
  67. if (likely(counter)) rrdset_next(st);
  68. rrddim_set_by_pointer(st, rd_min, error_min);
  69. rrddim_set_by_pointer(st, rd_max, error_max);
  70. rrddim_set_by_pointer(st, rd_avg, error_total / iterations);
  71. rrdset_done(st);
  72. }
  73. }
  74. netdata_thread_cleanup_pop(1);
  75. return NULL;
  76. }