1 //===-- xray_recursion_guard.h ---------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of XRay, a dynamic runtime instrumentation system.
11 //===----------------------------------------------------------------------===//
12 #ifndef XRAY_XRAY_RECURSION_GUARD_H
13 #define XRAY_XRAY_RECURSION_GUARD_H
15 #include "sanitizer_common/sanitizer_atomic.h"
19 /// The RecursionGuard is useful for guarding against signal handlers which are
20 /// also potentially calling XRay-instrumented functions. To use the
21 /// RecursionGuard, you'll typically need a thread_local atomic_uint8_t:
23 /// thread_local atomic_uint8_t Guard{0};
25 /// // In a handler function:
26 /// void handleArg0(int32_t F, XRayEntryType T) {
27 /// RecursionGuard G(Guard);
29 /// return; // Failed to acquire the guard.
33 class RecursionGuard
{
34 atomic_uint8_t
&Running
;
38 explicit inline RecursionGuard(atomic_uint8_t
&R
)
39 : Running(R
), Valid(!atomic_exchange(&R
, 1, memory_order_acq_rel
)) {}
41 inline RecursionGuard(const RecursionGuard
&) = delete;
42 inline RecursionGuard(RecursionGuard
&&) = delete;
43 inline RecursionGuard
&operator=(const RecursionGuard
&) = delete;
44 inline RecursionGuard
&operator=(RecursionGuard
&&) = delete;
46 explicit inline operator bool() const { return Valid
; }
48 inline ~RecursionGuard() noexcept
{
50 atomic_store(&Running
, 0, memory_order_release
);
56 #endif // XRAY_XRAY_RECURSION_GUARD_H