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 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x) __attribute__((x)) 43 #else 44 #define TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x) // no-op 45 #endif 46 47 // Document if a shared variable/field needs to be protected by a mutex. 48 // TF_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 TF_GUARDED_BY(x) TF_INTERNAL_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 TF_GUARDED_BY(mu1) TF_PT_GUARDED_BY(mu2); 62 #define TF_PT_GUARDED_BY(x) \ 63 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(pt_guarded_by(x)) 64 #define TF_PT_GUARDED_VAR // no-op 65 66 // Document the acquisition order between locks that can be held 67 // simultaneously by a thread. For any two locks that need to be annotated 68 // to establish an acquisition order, only one of them needs the annotation. 69 // (i.e. You don't have to annotate both locks with both TF_ACQUIRED_AFTER 70 // and TF_ACQUIRED_BEFORE.) 71 #define TF_ACQUIRED_AFTER(...) \ 72 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_after(__VA_ARGS__)) 73 74 #define TF_ACQUIRED_BEFORE(...) \ 75 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_before(__VA_ARGS__)) 76 77 #define TF_ACQUIRE(...) \ 78 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquire_capability(__VA_ARGS__)) 79 80 #define TF_ACQUIRE_SHARED(...) \ 81 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ 82 acquire_shared_capability(__VA_ARGS__)) 83 84 #define TF_RELEASE(...) \ 85 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(release_capability(__VA_ARGS__)) 86 87 // Document a function that expects a mutex to be held prior to entry. 88 // The mutex is expected to be held both on entry to and exit from the 89 // function. 90 #define TF_EXCLUSIVE_LOCKS_REQUIRED(...) \ 91 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(exclusive_locks_required(__VA_ARGS__)) 92 93 #define TF_SHARED_LOCKS_REQUIRED(...) \ 94 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_locks_required(__VA_ARGS__)) 95 96 // Document the locks acquired in the body of the function. These locks 97 // cannot be held when calling this function (for instance, when the 98 // mutex implementation is non-reentrant). 99 #define TF_LOCKS_EXCLUDED(...) \ 100 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(locks_excluded(__VA_ARGS__)) 101 102 // Document a function that returns a mutex without acquiring it. For example, 103 // a public getter method that returns a pointer to a private mutex should 104 // be annotated with TF_LOCK_RETURNED. 105 #define TF_LOCK_RETURNED(x) \ 106 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lock_returned(x)) 107 108 // Document if a class/type is a lockable type (such as the Mutex class). 109 #define TF_LOCKABLE TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lockable) 110 111 // Document if a class does RAII locking (such as the MutexLock class). 112 // The constructor should use LOCK_FUNCTION to specify the mutex that is 113 // acquired, and the destructor should use TF_UNLOCK_FUNCTION with no arguments; 114 // the analysis will assume that the destructor unlocks whatever the 115 // constructor locked. 116 #define TF_SCOPED_LOCKABLE \ 117 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(scoped_lockable) 118 119 // Document functions that acquire a lock in the body of a function, and do 120 // not release it. 121 #define TF_EXCLUSIVE_LOCK_FUNCTION(...) \ 122 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(exclusive_lock_function(__VA_ARGS__)) 123 124 #define TF_SHARED_LOCK_FUNCTION(...) \ 125 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_lock_function(__VA_ARGS__)) 126 127 // Document functions that expect a lock to be held on entry to the function, 128 // and release it in the body of the function. 129 #define TF_UNLOCK_FUNCTION(...) \ 130 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(unlock_function(__VA_ARGS__)) 131 132 // Document functions that try to acquire a lock, and return success or failure 133 // (or a non-boolean value that can be interpreted as a boolean). 134 // The first argument should be true for functions that return true on success, 135 // or false for functions that return false on success. The second argument 136 // specifies the mutex that is locked on success. If unspecified, it is assumed 137 // to be 'this'. 138 #define TF_EXCLUSIVE_TRYLOCK_FUNCTION(...) \ 139 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ 140 exclusive_trylock_function(__VA_ARGS__)) 141 142 #define TF_SHARED_TRYLOCK_FUNCTION(...) \ 143 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_trylock_function(__VA_ARGS__)) 144 145 // Document functions that dynamically check to see if a lock is held, and fail 146 // if it is not held. 147 #define TF_ASSERT_EXCLUSIVE_LOCK(...) \ 148 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_exclusive_lock(__VA_ARGS__)) 149 150 #define TF_ASSERT_SHARED_LOCK(...) \ 151 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_shared_lock(__VA_ARGS__)) 152 153 // Turns off thread safety checking within the body of a particular function. 154 // This is used as an escape hatch for cases where either (a) the function 155 // is correct, but the locking is more complicated than the analyzer can handle, 156 // or (b) the function contains race conditions that are known to be benign. 157 #define TF_NO_THREAD_SAFETY_ANALYSIS \ 158 TF_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(no_thread_safety_analysis) 159 160 // TF_TS_UNCHECKED should be placed around lock expressions that are not valid 161 // C++ syntax, but which are present for documentation purposes. These 162 // annotations will be ignored by the analysis. 163 #define TF_TS_UNCHECKED(x) "" 164 165 #endif // TENSORFLOW_CORE_PLATFORM_THREAD_ANNOTATIONS_H_ 166