xref: /freebsd/contrib/jemalloc/src/witness.c (revision 4198293b2568c3fa287e7bde71162e9d442f4305)
11f0a49e8SJason Evans #define JEMALLOC_WITNESS_C_
2*b7eaed25SJason Evans #include "jemalloc/internal/jemalloc_preamble.h"
3*b7eaed25SJason Evans #include "jemalloc/internal/jemalloc_internal_includes.h"
4*b7eaed25SJason Evans 
5*b7eaed25SJason Evans #include "jemalloc/internal/assert.h"
6*b7eaed25SJason Evans #include "jemalloc/internal/malloc_io.h"
71f0a49e8SJason Evans 
81f0a49e8SJason Evans void
witness_init(witness_t * witness,const char * name,witness_rank_t rank,witness_comp_t * comp,void * opaque)91f0a49e8SJason Evans witness_init(witness_t *witness, const char *name, witness_rank_t rank,
10*b7eaed25SJason Evans     witness_comp_t *comp, void *opaque) {
111f0a49e8SJason Evans 	witness->name = name;
121f0a49e8SJason Evans 	witness->rank = rank;
131f0a49e8SJason Evans 	witness->comp = comp;
14*b7eaed25SJason Evans 	witness->opaque = opaque;
151f0a49e8SJason Evans }
161f0a49e8SJason Evans 
17*b7eaed25SJason Evans static void
witness_lock_error_impl(const witness_list_t * witnesses,const witness_t * witness)18*b7eaed25SJason Evans witness_lock_error_impl(const witness_list_t *witnesses,
19*b7eaed25SJason Evans     const witness_t *witness) {
201f0a49e8SJason Evans 	witness_t *w;
211f0a49e8SJason Evans 
221f0a49e8SJason Evans 	malloc_printf("<jemalloc>: Lock rank order reversal:");
231f0a49e8SJason Evans 	ql_foreach(w, witnesses, link) {
241f0a49e8SJason Evans 		malloc_printf(" %s(%u)", w->name, w->rank);
251f0a49e8SJason Evans 	}
261f0a49e8SJason Evans 	malloc_printf(" %s(%u)\n", witness->name, witness->rank);
271f0a49e8SJason Evans 	abort();
281f0a49e8SJason Evans }
29*b7eaed25SJason Evans witness_lock_error_t *JET_MUTABLE witness_lock_error = witness_lock_error_impl;
301f0a49e8SJason Evans 
31*b7eaed25SJason Evans static void
witness_owner_error_impl(const witness_t * witness)32*b7eaed25SJason Evans witness_owner_error_impl(const witness_t *witness) {
331f0a49e8SJason Evans 	malloc_printf("<jemalloc>: Should own %s(%u)\n", witness->name,
341f0a49e8SJason Evans 	    witness->rank);
351f0a49e8SJason Evans 	abort();
361f0a49e8SJason Evans }
37*b7eaed25SJason Evans witness_owner_error_t *JET_MUTABLE witness_owner_error =
38*b7eaed25SJason Evans     witness_owner_error_impl;
391f0a49e8SJason Evans 
40*b7eaed25SJason Evans static void
witness_not_owner_error_impl(const witness_t * witness)41*b7eaed25SJason Evans witness_not_owner_error_impl(const witness_t *witness) {
421f0a49e8SJason Evans 	malloc_printf("<jemalloc>: Should not own %s(%u)\n", witness->name,
431f0a49e8SJason Evans 	    witness->rank);
441f0a49e8SJason Evans 	abort();
451f0a49e8SJason Evans }
46*b7eaed25SJason Evans witness_not_owner_error_t *JET_MUTABLE witness_not_owner_error =
47*b7eaed25SJason Evans     witness_not_owner_error_impl;
481f0a49e8SJason Evans 
49*b7eaed25SJason Evans static void
witness_depth_error_impl(const witness_list_t * witnesses,witness_rank_t rank_inclusive,unsigned depth)50*b7eaed25SJason Evans witness_depth_error_impl(const witness_list_t *witnesses,
518244f2aaSJason Evans     witness_rank_t rank_inclusive, unsigned depth) {
521f0a49e8SJason Evans 	witness_t *w;
531f0a49e8SJason Evans 
548244f2aaSJason Evans 	malloc_printf("<jemalloc>: Should own %u lock%s of rank >= %u:", depth,
558244f2aaSJason Evans 	    (depth != 1) ?  "s" : "", rank_inclusive);
561f0a49e8SJason Evans 	ql_foreach(w, witnesses, link) {
571f0a49e8SJason Evans 		malloc_printf(" %s(%u)", w->name, w->rank);
581f0a49e8SJason Evans 	}
591f0a49e8SJason Evans 	malloc_printf("\n");
601f0a49e8SJason Evans 	abort();
611f0a49e8SJason Evans }
62*b7eaed25SJason Evans witness_depth_error_t *JET_MUTABLE witness_depth_error =
63*b7eaed25SJason Evans     witness_depth_error_impl;
641f0a49e8SJason Evans 
651f0a49e8SJason Evans void
witnesses_cleanup(witness_tsd_t * witness_tsd)66*b7eaed25SJason Evans witnesses_cleanup(witness_tsd_t *witness_tsd) {
67*b7eaed25SJason Evans 	witness_assert_lockless(witness_tsd_tsdn(witness_tsd));
681f0a49e8SJason Evans 
691f0a49e8SJason Evans 	/* Do nothing. */
701f0a49e8SJason Evans }
711f0a49e8SJason Evans 
721f0a49e8SJason Evans void
witness_prefork(witness_tsd_t * witness_tsd)73*b7eaed25SJason Evans witness_prefork(witness_tsd_t *witness_tsd) {
74*b7eaed25SJason Evans 	if (!config_debug) {
75*b7eaed25SJason Evans 		return;
76*b7eaed25SJason Evans 	}
77*b7eaed25SJason Evans 	witness_tsd->forking = true;
781f0a49e8SJason Evans }
791f0a49e8SJason Evans 
801f0a49e8SJason Evans void
witness_postfork_parent(witness_tsd_t * witness_tsd)81*b7eaed25SJason Evans witness_postfork_parent(witness_tsd_t *witness_tsd) {
82*b7eaed25SJason Evans 	if (!config_debug) {
83*b7eaed25SJason Evans 		return;
84*b7eaed25SJason Evans 	}
85*b7eaed25SJason Evans 	witness_tsd->forking = false;
861f0a49e8SJason Evans }
871f0a49e8SJason Evans 
881f0a49e8SJason Evans void
witness_postfork_child(witness_tsd_t * witness_tsd)89*b7eaed25SJason Evans witness_postfork_child(witness_tsd_t *witness_tsd) {
90*b7eaed25SJason Evans 	if (!config_debug) {
91*b7eaed25SJason Evans 		return;
921f0a49e8SJason Evans 	}
931f0a49e8SJason Evans #ifndef JEMALLOC_MUTEX_INIT_CB
941f0a49e8SJason Evans 	witness_list_t *witnesses;
951f0a49e8SJason Evans 
96*b7eaed25SJason Evans 	witnesses = &witness_tsd->witnesses;
971f0a49e8SJason Evans 	ql_new(witnesses);
981f0a49e8SJason Evans #endif
99*b7eaed25SJason Evans 	witness_tsd->forking = false;
1001f0a49e8SJason Evans }
101