• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 // This header file contains the macro definitions for thread safety
17 // annotations that allow the developers to document the locking policies
18 // of their multi-threaded code. The annotations can also help program
19 // analysis tools to identify potential thread safety issues.
20 //
21 // The primary documentation on these annotations is external:
22 // http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
23 //
24 // The annotations are implemented using compiler attributes.
25 // Using the macros defined here instead of the raw attributes allows
26 // for portability and future compatibility.
27 //
28 // When referring to mutexes in the arguments of the attributes, you should
29 // use variable names or more complex expressions (e.g. my_object->mutex_)
30 // that evaluate to a concrete mutex object whenever possible. If the mutex
31 // you want to refer to is not in scope, you may use a member pointer
32 // (e.g. &MyClass::mutex_) to refer to a mutex in some (unknown) object.
33 //
34 
35 #ifndef TENSORFLOW_CORE_PLATFORM_THREAD_ANNOTATIONS_H_
36 #define TENSORFLOW_CORE_PLATFORM_THREAD_ANNOTATIONS_H_
37 
38 // IWYU pragma: private, include "third_party/tensorflow/core/platform/thread_annotations.h"
39 // IWYU pragma: friend third_party/tensorflow/core/platform/thread_annotations.h
40 
41 #if defined(__clang__) && (!defined(SWIG))
42 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
43 #else
44 #define THREAD_ANNOTATION_ATTRIBUTE__(x)  // no-op
45 #endif
46 
47 // Document if a shared variable/field needs to be protected by a mutex.
48 // GUARDED_BY allows the user to specify a particular mutex that should be
49 // held when accessing the annotated variable.  GUARDED_VAR indicates that
50 // a shared variable is guarded by some unspecified mutex, for use in rare
51 // cases where a valid mutex expression cannot be specified.
52 #define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
53 #define GUARDED_VAR  // no-op
54 
55 // Document if the memory location pointed to by a pointer should be guarded
56 // by a mutex when dereferencing the pointer.  PT_GUARDED_VAR is analogous to
57 // GUARDED_VAR.   Note that a pointer variable to a shared memory location
58 // could itself be a shared variable. For example, if a shared global pointer
59 // q, which is guarded by mu1, points to a shared memory location that is
60 // guarded by mu2, q should be annotated as follows:
61 //     int *q GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
62 #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
63 #define PT_GUARDED_VAR  // no-op
64 
65 // Document the acquisition order between locks that can be held
66 // simultaneously by a thread. For any two locks that need to be annotated
67 // to establish an acquisition order, only one of them needs the annotation.
68 // (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER
69 // and ACQUIRED_BEFORE.)
70 #define ACQUIRED_AFTER(...) \
71   THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
72 
73 #define ACQUIRED_BEFORE(...) \
74   THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
75 
76 #define ACQUIRE(...) \
77   THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
78 
79 #define ACQUIRE_SHARED(...) \
80   THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
81 
82 #define RELEASE(...) \
83   THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
84 
85 // Document a function that expects a mutex to be held prior to entry.
86 // The mutex is expected to be held both on entry to and exit from the
87 // function.
88 #define EXCLUSIVE_LOCKS_REQUIRED(...) \
89   THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
90 
91 #define SHARED_LOCKS_REQUIRED(...) \
92   THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
93 
94 // Document the locks acquired in the body of the function. These locks
95 // cannot be held when calling this function (for instance, when the
96 // mutex implementation is non-reentrant).
97 #define LOCKS_EXCLUDED(...) \
98   THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
99 
100 // Document a function that returns a mutex without acquiring it.  For example,
101 // a public getter method that returns a pointer to a private mutex should
102 // be annotated with LOCK_RETURNED.
103 #define LOCK_RETURNED(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
104 
105 // Document if a class/type is a lockable type (such as the Mutex class).
106 #define LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(lockable)
107 
108 // Document if a class does RAII locking (such as the MutexLock class).
109 // The constructor should use LOCK_FUNCTION to specify the mutex that is
110 // acquired, and the destructor should use UNLOCK_FUNCTION with no arguments;
111 // the analysis will assume that the destructor unlocks whatever the
112 // constructor locked.
113 #define SCOPED_LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
114 
115 // Document functions that acquire a lock in the body of a function, and do
116 // not release it.
117 #define EXCLUSIVE_LOCK_FUNCTION(...) \
118   THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
119 
120 #define SHARED_LOCK_FUNCTION(...) \
121   THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
122 
123 // Document functions that expect a lock to be held on entry to the function,
124 // and release it in the body of the function.
125 #define UNLOCK_FUNCTION(...) \
126   THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
127 
128 // Document functions that try to acquire a lock, and return success or failure
129 // (or a non-boolean value that can be interpreted as a boolean).
130 // The first argument should be true for functions that return true on success,
131 // or false for functions that return false on success. The second argument
132 // specifies the mutex that is locked on success. If unspecified, it is assumed
133 // to be 'this'.
134 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
135   THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
136 
137 #define SHARED_TRYLOCK_FUNCTION(...) \
138   THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
139 
140 // Document functions that dynamically check to see if a lock is held, and fail
141 // if it is not held.
142 #define ASSERT_EXCLUSIVE_LOCK(...) \
143   THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
144 
145 #define ASSERT_SHARED_LOCK(...) \
146   THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
147 
148 // Turns off thread safety checking within the body of a particular function.
149 // This is used as an escape hatch for cases where either (a) the function
150 // is correct, but the locking is more complicated than the analyzer can handle,
151 // or (b) the function contains race conditions that are known to be benign.
152 #define NO_THREAD_SAFETY_ANALYSIS \
153   THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
154 
155 // TS_UNCHECKED should be placed around lock expressions that are not valid
156 // C++ syntax, but which are present for documentation purposes.  These
157 // annotations will be ignored by the analysis.
158 #define TS_UNCHECKED(x) ""
159 
160 namespace tensorflow {
161 namespace thread_safety_analysis {
162 
163 // Takes a reference to a guarded data member, and returns an unguarded
164 // reference.
165 template <class T>
ts_unchecked_read(const T & v)166 inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS {
167   return v;
168 }
169 
170 template <class T>
ts_unchecked_read(T & v)171 inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS {
172   return v;
173 }
174 }  // namespace thread_safety_analysis
175 }  // namespace tensorflow
176 
177 #endif  // TENSORFLOW_CORE_PLATFORM_THREAD_ANNOTATIONS_H_
178