prof_thread_name.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. expect_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. expect_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. expect_d_eq(mallctl("thread.prof.name", NULL, NULL,
  21. (void *)&thread_name, sizeof(thread_name)), 0,
  22. "%s():%d: Unexpected mallctl failure writing 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. test_skip_if(opt_prof_sys_thread_name);
  32. mallctl_thread_name_get("");
  33. mallctl_thread_name_set("hi there");
  34. /* NULL input shouldn't be allowed. */
  35. thread_name = NULL;
  36. expect_d_eq(mallctl("thread.prof.name", NULL, NULL,
  37. (void *)&thread_name, sizeof(thread_name)), EFAULT,
  38. "Unexpected mallctl result writing \"%s\" to thread.prof.name",
  39. thread_name);
  40. /* '\n' shouldn't be allowed. */
  41. thread_name = "hi\nthere";
  42. expect_d_eq(mallctl("thread.prof.name", NULL, NULL,
  43. (void *)&thread_name, sizeof(thread_name)), EFAULT,
  44. "Unexpected mallctl result writing \"%s\" to thread.prof.name",
  45. thread_name);
  46. /* Simultaneous read/write shouldn't be allowed. */
  47. {
  48. const char *thread_name_old;
  49. size_t sz;
  50. sz = sizeof(thread_name_old);
  51. expect_d_eq(mallctl("thread.prof.name",
  52. (void *)&thread_name_old, &sz, (void *)&thread_name,
  53. sizeof(thread_name)), EPERM,
  54. "Unexpected mallctl result writing \"%s\" to "
  55. "thread.prof.name", thread_name);
  56. }
  57. mallctl_thread_name_set("");
  58. }
  59. TEST_END
  60. #define NTHREADS 4
  61. #define NRESET 25
  62. static void *
  63. thd_start(void *varg) {
  64. unsigned thd_ind = *(unsigned *)varg;
  65. char thread_name[16] = "";
  66. unsigned i;
  67. malloc_snprintf(thread_name, sizeof(thread_name), "thread %u", thd_ind);
  68. mallctl_thread_name_get("");
  69. mallctl_thread_name_set(thread_name);
  70. for (i = 0; i < NRESET; i++) {
  71. expect_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
  72. "Unexpected error while resetting heap profile data");
  73. mallctl_thread_name_get(thread_name);
  74. }
  75. mallctl_thread_name_set(thread_name);
  76. mallctl_thread_name_set("");
  77. return NULL;
  78. }
  79. TEST_BEGIN(test_prof_thread_name_threaded) {
  80. test_skip_if(!config_prof);
  81. test_skip_if(opt_prof_sys_thread_name);
  82. thd_t thds[NTHREADS];
  83. unsigned thd_args[NTHREADS];
  84. unsigned i;
  85. for (i = 0; i < NTHREADS; i++) {
  86. thd_args[i] = i;
  87. thd_create(&thds[i], thd_start, (void *)&thd_args[i]);
  88. }
  89. for (i = 0; i < NTHREADS; i++) {
  90. thd_join(thds[i], NULL);
  91. }
  92. }
  93. TEST_END
  94. #undef NTHREADS
  95. #undef NRESET
  96. int
  97. main(void) {
  98. return test(
  99. test_prof_thread_name_validation,
  100. test_prof_thread_name_threaded);
  101. }