prof_log.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "test/jemalloc_test.h"
  2. #include "jemalloc/internal/prof_log.h"
  3. #define N_PARAM 100
  4. #define N_THREADS 10
  5. static void expect_rep() {
  6. expect_b_eq(prof_log_rep_check(), false, "Rep check failed");
  7. }
  8. static void expect_log_empty() {
  9. expect_zu_eq(prof_log_bt_count(), 0,
  10. "The log has backtraces; it isn't empty");
  11. expect_zu_eq(prof_log_thr_count(), 0,
  12. "The log has threads; it isn't empty");
  13. expect_zu_eq(prof_log_alloc_count(), 0,
  14. "The log has allocations; it isn't empty");
  15. }
  16. void *buf[N_PARAM];
  17. static void f() {
  18. int i;
  19. for (i = 0; i < N_PARAM; i++) {
  20. buf[i] = malloc(100);
  21. }
  22. for (i = 0; i < N_PARAM; i++) {
  23. free(buf[i]);
  24. }
  25. }
  26. TEST_BEGIN(test_prof_log_many_logs) {
  27. int i;
  28. test_skip_if(!config_prof);
  29. for (i = 0; i < N_PARAM; i++) {
  30. expect_b_eq(prof_log_is_logging(), false,
  31. "Logging shouldn't have started yet");
  32. expect_d_eq(mallctl("prof.log_start", NULL, NULL, NULL, 0), 0,
  33. "Unexpected mallctl failure when starting logging");
  34. expect_b_eq(prof_log_is_logging(), true,
  35. "Logging should be started by now");
  36. expect_log_empty();
  37. expect_rep();
  38. f();
  39. expect_zu_eq(prof_log_thr_count(), 1, "Wrong thread count");
  40. expect_rep();
  41. expect_b_eq(prof_log_is_logging(), true,
  42. "Logging should still be on");
  43. expect_d_eq(mallctl("prof.log_stop", NULL, NULL, NULL, 0), 0,
  44. "Unexpected mallctl failure when stopping logging");
  45. expect_b_eq(prof_log_is_logging(), false,
  46. "Logging should have turned off");
  47. }
  48. }
  49. TEST_END
  50. thd_t thr_buf[N_THREADS];
  51. static void *f_thread(void *unused) {
  52. int i;
  53. for (i = 0; i < N_PARAM; i++) {
  54. void *p = malloc(100);
  55. memset(p, 100, 1);
  56. free(p);
  57. }
  58. return NULL;
  59. }
  60. TEST_BEGIN(test_prof_log_many_threads) {
  61. test_skip_if(!config_prof);
  62. int i;
  63. expect_d_eq(mallctl("prof.log_start", NULL, NULL, NULL, 0), 0,
  64. "Unexpected mallctl failure when starting logging");
  65. for (i = 0; i < N_THREADS; i++) {
  66. thd_create(&thr_buf[i], &f_thread, NULL);
  67. }
  68. for (i = 0; i < N_THREADS; i++) {
  69. thd_join(thr_buf[i], NULL);
  70. }
  71. expect_zu_eq(prof_log_thr_count(), N_THREADS,
  72. "Wrong number of thread entries");
  73. expect_rep();
  74. expect_d_eq(mallctl("prof.log_stop", NULL, NULL, NULL, 0), 0,
  75. "Unexpected mallctl failure when stopping logging");
  76. }
  77. TEST_END
  78. static void f3() {
  79. void *p = malloc(100);
  80. free(p);
  81. }
  82. static void f1() {
  83. void *p = malloc(100);
  84. f3();
  85. free(p);
  86. }
  87. static void f2() {
  88. void *p = malloc(100);
  89. free(p);
  90. }
  91. TEST_BEGIN(test_prof_log_many_traces) {
  92. test_skip_if(!config_prof);
  93. expect_d_eq(mallctl("prof.log_start", NULL, NULL, NULL, 0), 0,
  94. "Unexpected mallctl failure when starting logging");
  95. int i;
  96. expect_rep();
  97. expect_log_empty();
  98. for (i = 0; i < N_PARAM; i++) {
  99. expect_rep();
  100. f1();
  101. expect_rep();
  102. f2();
  103. expect_rep();
  104. f3();
  105. expect_rep();
  106. }
  107. /*
  108. * There should be 8 total backtraces: two for malloc/free in f1(), two
  109. * for malloc/free in f2(), two for malloc/free in f3(), and then two
  110. * for malloc/free in f1()'s call to f3(). However compiler
  111. * optimizations such as loop unrolling might generate more call sites.
  112. * So >= 8 traces are expected.
  113. */
  114. expect_zu_ge(prof_log_bt_count(), 8,
  115. "Expect at least 8 backtraces given sample workload");
  116. expect_d_eq(mallctl("prof.log_stop", NULL, NULL, NULL, 0), 0,
  117. "Unexpected mallctl failure when stopping logging");
  118. }
  119. TEST_END
  120. int
  121. main(void) {
  122. if (config_prof) {
  123. prof_log_dummy_set(true);
  124. }
  125. return test_no_reentrancy(
  126. test_prof_log_many_logs,
  127. test_prof_log_many_traces,
  128. test_prof_log_many_threads);
  129. }