Coverage Report

Created: 2026-05-08 18:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/common/thread_safety_annotations.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
// Thread safety annotation macros and annotated mutex wrappers for
19
// Clang's -Wthread-safety static analysis.
20
// Reference: https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
21
22
#pragma once
23
24
#include <mutex>
25
26
#ifdef BE_TEST
27
namespace doris {
28
void mock_random_sleep();
29
} // namespace doris
30
#endif
31
32
// Enable thread safety attributes only with clang.
33
// The attributes can be safely erased when compiling with other compilers.
34
#if defined(__clang__) && (!defined(SWIG))
35
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
36
#else
37
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
38
#endif
39
40
#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
41
42
#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
43
44
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
45
46
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
47
48
#define ACQUIRED_BEFORE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
49
50
#define ACQUIRED_AFTER(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
51
52
#define REQUIRES(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
53
54
#define REQUIRES_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
55
56
#define ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
57
58
#define ACQUIRE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
59
60
#define RELEASE(...) THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
61
62
#define RELEASE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
63
64
#define TRY_ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
65
66
#define TRY_ACQUIRE_SHARED(...) \
67
    THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
68
69
#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
70
71
#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
72
73
#define ASSERT_SHARED_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
74
75
#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
76
77
#define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
78
79
// Annotated mutex wrapper for use with Clang thread safety analysis.
80
// Wraps std::mutex and provides the CAPABILITY annotation so that
81
// GUARDED_BY / REQUIRES / etc. annotations can reference it.
82
class CAPABILITY("mutex") AnnotatedMutex {
83
public:
84
93.2k
    void lock() ACQUIRE() { _mutex.lock(); }
85
93.4k
    void unlock() RELEASE() { _mutex.unlock(); }
86
0
    bool try_lock() TRY_ACQUIRE(true) { return _mutex.try_lock(); }
87
88
    // Access the underlying std::mutex (e.g., for std::condition_variable).
89
    // Use with care — this bypasses thread safety annotations.
90
0
    std::mutex& native_handle() { return _mutex; }
91
92
private:
93
    std::mutex _mutex;
94
};
95
96
// RAII scoped lock guard annotated for thread safety analysis.
97
// In BE_TEST builds, injects a random sleep before acquiring and after
98
// releasing the lock to exercise concurrent code paths.
99
template <typename MutexType>
100
class SCOPED_CAPABILITY LockGuard {
101
public:
102
93.3k
    explicit LockGuard(MutexType& mu) ACQUIRE(mu) : _mu(mu) {
103
#ifdef BE_TEST
104
        doris::mock_random_sleep();
105
#endif
106
93.3k
        _mu.lock();
107
93.3k
    }
108
93.5k
    ~LockGuard() RELEASE() {
109
93.5k
        _mu.unlock();
110
#ifdef BE_TEST
111
        doris::mock_random_sleep();
112
#endif
113
93.5k
    }
114
115
    LockGuard(const LockGuard&) = delete;
116
    LockGuard& operator=(const LockGuard&) = delete;
117
118
private:
119
    MutexType& _mu;
120
};