prof_thread_name.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "test/jemalloc_test.h"
  2. static void
  3. mallctl_thread_name_get_impl(const char *thread_name_expected, const char *func,
  4. int line) {
  5. const char *thread_name_old;
  6. size_t sz;
  7. sz = sizeof(thread_name_old);
  8. assert_d_eq(mallctl("thread.prof.name", (void *)&thread_name_old, &sz,
  9. NULL, 0), 0,
  10. "%s():%d: Unexpected mallctl failure reading thread.prof.name",
  11. func, line);
  12. assert_str_eq(thread_name_old, thread_name_expected,
  13. "%s():%d: Unexpected thread.prof.name value", func, line);
  14. }
  15. #define mallctl_thread_name_get(a) \
  16. mallctl_thread_name_get_impl(a, __func__, __LINE__)
  17. static void
  18. mallctl_thread_name_set_impl(const char *thread_name, const char *func,
  19. int line) {
  20. assert_d_eq(mallctl("thread.prof.name", NULL, NULL,
  21. (void *)&thread_name, sizeof(thread_name)), 0,
  22. "%s():%d: Unexpected mallctl failure reading thread.prof.name",
  23. func, line);
  24. mallctl_thread_name_get_impl(thread_name, func, line);
  25. }
  26. #define mallctl_thread_name_set(a) \
  27. mallctl_thread_name_set_impl(a, __func__, __LINE__)
  28. TEST_BEGIN(test_prof_thread_name_validation) {
  29. const char *thread_name;
  30. test_skip_if(!config_prof);
  31. mallctl_thread_name_get("");
  32. mallctl_thread_name_set("hi there");
  33. /* NULL input shouldn't be allowed. */
  34. thread_name = NULL;
  35. assert_d_eq(mallctl("thread.prof.name", NULL, NULL,
  36. (void *)&thread_name, sizeof(thread_name)), EFAULT,
  37. "Unexpected mallctl result writing \"%s\" to thread.prof.name",
  38. thread_name);
  39. /* '\n' shouldn't be allowed. */
  40. thread_name = "hi\nthere";
  41. assert_d_eq(mallctl("thread.prof.name", NULL, NULL,
  42. (void *)&thread_name, sizeof(thread_name)), EFAULT,
  43. "Unexpected mallctl result writing \"%s\" to thread.prof.name",
  44. thread_name);
  45. /* Simultaneous read/write shouldn't be allowed. */
  46. {
  47. const char *thread_name_old;
  48. size_t sz;
  49. sz = sizeof(thread_name_old);
  50. assert_d_eq(mallctl("thread.prof.name",
  51. (void *)&thread_name_old, &sz, (void *)&thread_name,
  52. sizeof(thread_name)), EPERM,
  53. "Unexpected mallctl result writing \"%s\" to "
  54. "thread.prof.name", thread_name);
  55. }
  56. mallctl_thread_name_set("");
  57. }
  58. TEST_END
  59. #define NTHREADS 4
  60. #define NRESET 25
  61. static void *
  62. thd_start(void *varg) {
  63. unsigned thd_ind = *(unsigned *)varg;
  64. char thread_name[16] = "";
  65. unsigned i;
  66. malloc_snprintf(thread_name, sizeof(thread_name), "thread %u", thd_ind);
  67. mallctl_thread_name_get("");
  68. mallctl_thread_name_set(thread_name);
  69. for (i = 0; i < NRESET; i++) {
  70. assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
  71. "Unexpected error while resetting heap profile data");
  72. mallctl_thread_name_get(thread_name);
  73. }
  74. mallctl_thread_name_set(thread_name);
  75. mallctl_thread_name_set("");
  76. return NULL;
  77. }
  78. TEST_BEGIN(test_prof_thread_name_threaded) {
  79. thd_t thds[NTHREADS];
  80. unsigned thd_args[NTHREADS];
  81. unsigned i;
  82. test_skip_if(!config_prof);
  83. for (i = 0; i < NTHREADS; i++) {
  84. thd_args[i] = i;
  85. thd_create(&thds[i], thd_start, (void *)&thd_args[i]);
  86. }
  87. for (i = 0; i < NTHREADS; i++) {
  88. thd_join(thds[i], NULL);
  89. }
  90. }
  91. TEST_END
  92. #undef NTHREADS
  93. #undef NRESET
  94. int
  95. main(void) {
  96. return test(
  97. test_prof_thread_name_validation,
  98. test_prof_thread_name_threaded);
  99. }