Line data Source code
1 : // Copyright 2024 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 : // of this source code is governed by a BSD-style license that can be found in 3 : // the LICENSE file. 4 : 5 : package invariants 6 : 7 : import ( 8 : "math/rand/v2" 9 : "runtime" 10 : 11 : "github.com/cockroachdb/pebble/internal/buildtags" 12 : ) 13 : 14 : // Enabled is true if we were built with the "invariants" or "race" build tags. 15 : // 16 : // Enabled should be used to gate invariant checks that may be expensive. It 17 : // should not be used to unconditionally alter a code path significantly (e.g. 18 : // wrapping an iterator - see #3678); Sometimes() should be used instead so that 19 : // the production code path gets test coverage as well. 20 : const Enabled = buildtags.Race || buildtags.Invariants 21 : 22 : // RaceEnabled is true if we were built with the "race" build tag. 23 : const RaceEnabled = buildtags.Race 24 : 25 : // Sometimes returns true percent% of the time if invariants are Enabled (i.e. 26 : // we were built with the "invariants" or "race" build tags). Otherwise, always 27 : // returns false. 28 1 : func Sometimes(percent int) bool { 29 1 : return Enabled && rand.Uint32N(100) < uint32(percent) 30 1 : } 31 : 32 : // UseFinalizers is true if we want to use finalizers for assertions around 33 : // object lifetime and cleanup. This happens when the invariants or tracing tags 34 : // are set, but we exclude race builds because we historically ran into some 35 : // finalizer-related race detector bugs. 36 : const UseFinalizers = !buildtags.Race && (buildtags.Invariants || buildtags.Tracing) 37 : 38 : // SetFinalizer is a wrapper around runtime.SetFinalizer that is a no-op under 39 : // race builds or if neither the invariants nor tracing build tags are 40 : // specified. 41 : // 42 : // We exclude race builds because we historically ran into some race detector 43 : // bugs related to finalizers. 44 : // 45 : // This function is a no-op if UseFinalizers is false and it should inline to 46 : // nothing. 47 1 : func SetFinalizer(obj, finalizer interface{}) { 48 1 : if UseFinalizers { 49 1 : runtime.SetFinalizer(obj, finalizer) 50 1 : } 51 : }