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
7void
8witness_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
16static void
17witness_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
26static void
27witness_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
47static void
48witness_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}
55witness_lock_error_t *JET_MUTABLE witness_lock_error = witness_lock_error_impl;
56
57static void
58witness_owner_error_impl(const witness_t *witness) {
59 malloc_printf("<jemalloc>: Should own %s(%u)\n", witness->name,
60 witness->rank);
61 abort();
62}
63witness_owner_error_t *JET_MUTABLE witness_owner_error =
64 witness_owner_error_impl;
65
66static void
67witness_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}
72witness_not_owner_error_t *JET_MUTABLE witness_not_owner_error =
73 witness_not_owner_error_impl;
74
75static void
76witness_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}
84witness_depth_error_t *JET_MUTABLE witness_depth_error =
85 witness_depth_error_impl;
86
87void
88witnesses_cleanup(witness_tsd_t *witness_tsd) {
89 witness_assert_lockless(witness_tsd_tsdn(witness_tsd));
90
91 /* Do nothing. */
92}
93
94void
95witness_prefork(witness_tsd_t *witness_tsd) {
96 if (!config_debug) {
97 return;
98 }
99 witness_tsd->forking = true;
100}
101
102void
103witness_postfork_parent(witness_tsd_t *witness_tsd) {
104 if (!config_debug) {
105 return;
106 }
107 witness_tsd->forking = false;
108}
109
110void
111witness_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