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