1 #include "jemalloc/internal/jemalloc_preamble.h" 2 #include "jemalloc/internal/jemalloc_internal_includes.h" 3 4 #include "jemalloc/internal/assert.h" 5 #include "jemalloc/internal/malloc_io.h" 6 7 void 8 witness_init(witness_t *witness, const char *name, witness_rank_t rank, 9 witness_comp_t *comp, void *opaque) { 10 witness->name = name; 11 witness->rank = rank; 12 witness->comp = comp; 13 witness->opaque = opaque; 14 } 15 16 static void 17 witness_print_witness(witness_t *w, unsigned n) { 18 assert(n > 0); 19 if (n == 1) { 20 malloc_printf(" %s(%u)", w->name, w->rank); 21 } else { 22 malloc_printf(" %s(%u)X%u", w->name, w->rank, n); 23 } 24 } 25 26 static void 27 witness_print_witnesses(const witness_list_t *witnesses) { 28 witness_t *w, *last = NULL; 29 unsigned n = 0; 30 ql_foreach(w, witnesses, link) { 31 if (last != NULL && w->rank > last->rank) { 32 assert(w->name != last->name); 33 witness_print_witness(last, n); 34 n = 0; 35 } else if (last != NULL) { 36 assert(w->rank == last->rank); 37 assert(w->name == last->name); 38 } 39 last = w; 40 ++n; 41 } 42 if (last != NULL) { 43 witness_print_witness(last, n); 44 } 45 } 46 47 static void 48 witness_lock_error_impl(const witness_list_t *witnesses, 49 const witness_t *witness) { 50 malloc_printf("<jemalloc>: Lock rank order reversal:"); 51 witness_print_witnesses(witnesses); 52 malloc_printf(" %s(%u)\n", witness->name, witness->rank); 53 abort(); 54 } 55 witness_lock_error_t *JET_MUTABLE witness_lock_error = witness_lock_error_impl; 56 57 static void 58 witness_owner_error_impl(const witness_t *witness) { 59 malloc_printf("<jemalloc>: Should own %s(%u)\n", witness->name, 60 witness->rank); 61 abort(); 62 } 63 witness_owner_error_t *JET_MUTABLE witness_owner_error = 64 witness_owner_error_impl; 65 66 static void 67 witness_not_owner_error_impl(const witness_t *witness) { 68 malloc_printf("<jemalloc>: Should not own %s(%u)\n", witness->name, 69 witness->rank); 70 abort(); 71 } 72 witness_not_owner_error_t *JET_MUTABLE witness_not_owner_error = 73 witness_not_owner_error_impl; 74 75 static void 76 witness_depth_error_impl(const witness_list_t *witnesses, 77 witness_rank_t rank_inclusive, unsigned depth) { 78 malloc_printf("<jemalloc>: Should own %u lock%s of rank >= %u:", depth, 79 (depth != 1) ? "s" : "", rank_inclusive); 80 witness_print_witnesses(witnesses); 81 malloc_printf("\n"); 82 abort(); 83 } 84 witness_depth_error_t *JET_MUTABLE witness_depth_error = 85 witness_depth_error_impl; 86 87 void 88 witnesses_cleanup(witness_tsd_t *witness_tsd) { 89 witness_assert_lockless(witness_tsd_tsdn(witness_tsd)); 90 91 /* Do nothing. */ 92 } 93 94 void 95 witness_prefork(witness_tsd_t *witness_tsd) { 96 if (!config_debug) { 97 return; 98 } 99 witness_tsd->forking = true; 100 } 101 102 void 103 witness_postfork_parent(witness_tsd_t *witness_tsd) { 104 if (!config_debug) { 105 return; 106 } 107 witness_tsd->forking = false; 108 } 109 110 void 111 witness_postfork_child(witness_tsd_t *witness_tsd) { 112 if (!config_debug) { 113 return; 114 } 115 #ifndef JEMALLOC_MUTEX_INIT_CB 116 witness_list_t *witnesses; 117 118 witnesses = &witness_tsd->witnesses; 119 ql_new(witnesses); 120 #endif 121 witness_tsd->forking = false; 122 } 123