plugin_idlejitter.c 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
  6. static_thread->enabled = NETDATA_MAIN_THREAD_EXITING;
  7. info("cleaning up...");
  8. static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
  9. }
  10. void *cpuidlejitter_main(void *ptr) {
  11. netdata_thread_cleanup_push(cpuidlejitter_main_cleanup, ptr);
  12. usec_t sleep_ut = config_get_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS) * USEC_PER_MS;
  13. if(sleep_ut <= 0) {
  14. config_set_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS);
  15. sleep_ut = CPU_IDLEJITTER_SLEEP_TIME_MS * USEC_PER_MS;
  16. }
  17. RRDSET *st = rrdset_create_localhost(
  18. "system"
  19. , "idlejitter"
  20. , NULL
  21. , "idlejitter"
  22. , NULL
  23. , "CPU Idle Jitter"
  24. , "microseconds lost/s"
  25. , "idlejitter.plugin"
  26. , NULL
  27. , NETDATA_CHART_PRIO_SYSTEM_IDLEJITTER
  28. , localhost->rrd_update_every
  29. , RRDSET_TYPE_AREA
  30. );
  31. RRDDIM *rd_min = rrddim_add(st, "min", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  32. RRDDIM *rd_max = rrddim_add(st, "max", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  33. RRDDIM *rd_avg = rrddim_add(st, "average", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  34. usec_t update_every_ut = localhost->rrd_update_every * USEC_PER_SEC;
  35. struct timeval before, after;
  36. unsigned long long counter;
  37. for(counter = 0; 1 ;counter++) {
  38. int iterations = 0;
  39. usec_t error_total = 0,
  40. error_min = 0,
  41. error_max = 0,
  42. elapsed = 0;
  43. if(netdata_exit) break;
  44. while(elapsed < update_every_ut) {
  45. now_monotonic_high_precision_timeval(&before);
  46. sleep_usec(sleep_ut);
  47. now_monotonic_high_precision_timeval(&after);
  48. usec_t dt = dt_usec(&after, &before);
  49. elapsed += dt;
  50. usec_t error = dt - sleep_ut;
  51. error_total += error;
  52. if(unlikely(!iterations))
  53. error_min = error;
  54. else if(error < error_min)
  55. error_min = error;
  56. if(error > error_max)
  57. error_max = error;
  58. iterations++;
  59. }
  60. if(netdata_exit) break;
  61. if(iterations) {
  62. if (likely(counter)) rrdset_next(st);
  63. rrddim_set_by_pointer(st, rd_min, error_min);
  64. rrddim_set_by_pointer(st, rd_max, error_max);
  65. rrddim_set_by_pointer(st, rd_avg, error_total / iterations);
  66. rrdset_done(st);
  67. }
  68. }
  69. netdata_thread_cleanup_pop(1);
  70. return NULL;
  71. }