1// Copyright (c) 2008, Google Inc. 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: 7// 8// * Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// * Redistributions in binary form must reproduce the above 11// copyright notice, this list of conditions and the following disclaimer 12// in the documentation and/or other materials provided with the 13// distribution. 14// * Neither the name of Google Inc. nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30// --- 31// Author: Le-Chun Wu 32// 33// This header file contains the macro definitions for thread safety 34// annotations that allow the developers to document the locking policies 35// of their multi-threaded code. The annotations can also help program 36// analysis tools to identify potential thread safety issues. 37// 38// The annotations are implemented using GCC's "attributes" extension. 39// Using the macros defined here instead of the raw GCC attributes allows 40// for portability and future compatibility. 41// 42// This functionality is not yet fully implemented in perftools, 43// but may be one day. 44 45#ifndef BASE_THREAD_ANNOTATIONS_H_ 46#define BASE_THREAD_ANNOTATIONS_H_ 47 48 49#if defined(__GNUC__) \ 50 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ 51 && defined(__SUPPORT_TS_ANNOTATION__) && (!defined(SWIG)) 52#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) 53#else 54#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op 55#endif 56 57 58// Document if a shared variable/field needs to be protected by a lock. 59// GUARDED_BY allows the user to specify a particular lock that should be 60// held when accessing the annotated variable, while GUARDED_VAR only 61// indicates a shared variable should be guarded (by any lock). GUARDED_VAR 62// is primarily used when the client cannot express the name of the lock. 63#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) 64#define GUARDED_VAR THREAD_ANNOTATION_ATTRIBUTE__(guarded) 65 66// Document if the memory location pointed to by a pointer should be guarded 67// by a lock when dereferencing the pointer. Similar to GUARDED_VAR, 68// PT_GUARDED_VAR is primarily used when the client cannot express the name 69// of the lock. Note that a pointer variable to a shared memory location 70// could itself be a shared variable. For example, if a shared global pointer 71// q, which is guarded by mu1, points to a shared memory location that is 72// guarded by mu2, q should be annotated as follows: 73// int *q GUARDED_BY(mu1) PT_GUARDED_BY(mu2); 74#define PT_GUARDED_BY(x) \ 75 THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x)) 76#define PT_GUARDED_VAR \ 77 THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded) 78 79// Document the acquisition order between locks that can be held 80// simultaneously by a thread. For any two locks that need to be annotated 81// to establish an acquisition order, only one of them needs the annotation. 82// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER 83// and ACQUIRED_BEFORE.) 84#define ACQUIRED_AFTER(x) \ 85 THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x)) 86#define ACQUIRED_BEFORE(x) \ 87 THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x)) 88 89// The following three annotations document the lock requirements for 90// functions/methods. 91 92// Document if a function expects certain locks to be held before it is called 93#define EXCLUSIVE_LOCKS_REQUIRED(x) \ 94 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x)) 95 96#define SHARED_LOCKS_REQUIRED(x) \ 97 THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(x)) 98 99// Document the locks acquired in the body of the function. These locks 100// cannot be held when calling this function (as google3's Mutex locks are 101// non-reentrant). 102#define LOCKS_EXCLUDED(x) \ 103 THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x)) 104 105// Document the lock the annotated function returns without acquiring it. 106#define LOCK_RETURNED(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) 107 108// Document if a class/type is a lockable type (such as the Mutex class). 109#define LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(lockable) 110 111// Document if a class is a scoped lockable type (such as the MutexLock class). 112#define SCOPED_LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) 113 114// The following annotations specify lock and unlock primitives. 115#define EXCLUSIVE_LOCK_FUNCTION(x) \ 116 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock(x)) 117 118#define SHARED_LOCK_FUNCTION(x) \ 119 THREAD_ANNOTATION_ATTRIBUTE__(shared_lock(x)) 120 121#define EXCLUSIVE_TRYLOCK_FUNCTION(x) \ 122 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock(x)) 123 124#define SHARED_TRYLOCK_FUNCTION(x) \ 125 THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock(x)) 126 127#define UNLOCK_FUNCTION(x) \ 128 THREAD_ANNOTATION_ATTRIBUTE__(unlock(x)) 129 130// An escape hatch for thread safety analysis to ignore the annotated function. 131#define NO_THREAD_SAFETY_ANALYSIS \ 132 THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) 133 134#endif // BASE_THREAD_ANNOTATIONS_H_ 135