Add lock annotations to <sys/cdefs.h>.

Clang has support for annotating mutexes and code that uses mutexes to
validate certain aspects of thread safety:

- Whether acquiring/releasing locks is done properly (e.g., whether you
  unlock a mutex before leaving a function).
- Whether a lock is held while reading/writing data from/to memory.

Analysis is performed at the function level. Functions can be annotated
to indicate they:

- (try to) pick up a lock,
- release a lock,
- can only be called when (not) holding a lock,
- assert that a lock is held.

Variables and structure members can be annotated to indicate that they
are guarded by a certain lock. In C++, these annotations can refer
to both global variables, but also other class/structure members. In C,
it is only possible to refer to global variables.

This change adds wrappers for the annotations used by Clang to
<sys/cdefs.h>. They currently have no effect, but this is on purpose.
This change will be merged back to FreeBSD 9 and 10, which means we can
safely experiment with these annotations on HEAD without making it
harder to port changes back.

Reviewed by:	announced on arch@ and toolchain@
MFC after:	3 weeks
This commit is contained in:
Ed Schouten 2014-09-01 18:27:04 +00:00
parent c1b0ea2c83
commit b2d6fddee7

View File

@ -739,4 +739,60 @@
#define __NO_TLS 1
#endif
/*
* Lock annotations.
*
* Clang provides support for doing basic thread-safety tests at
* compile-time, by marking which locks will/should be held when
* entering/leaving a functions.
*
* Furthermore, it is also possible to annotate variables and structure
* members to enforce that they are only accessed when certain locks are
* held.
*
* Note: These annotations have no effect on this version of FreeBSD.
* They are merely provided for forward compatibilty.
*/
#define __lock_annotate(x)
/* Structure implements a lock. */
#define __lockable __lock_annotate(lockable)
/* Function acquires an exclusive or shared lock. */
#define __locks_exclusive(...) \
__lock_annotate(exclusive_lock_function(__VA_ARGS__))
#define __locks_shared(...) \
__lock_annotate(shared_lock_function(__VA_ARGS__))
/* Function attempts to acquire an exclusive or shared lock. */
#define __trylocks_exclusive(...) \
__lock_annotate(exclusive_trylock_function(__VA_ARGS__))
#define __trylocks_shared(...) \
__lock_annotate(shared_trylock_function(__VA_ARGS__))
/* Function releases a lock. */
#define __unlocks(...) __lock_annotate(unlock_function(__VA_ARGS__))
/* Function asserts that an exclusive or shared lock is held. */
#define __asserts_exclusive(...) \
__lock_annotate(assert_exclusive_lock(__VA_ARGS__))
#define __asserts_shared(...) \
__lock_annotate(assert_shared_lock(__VA_ARGS__))
/* Function requires that an exclusive or shared lock is or is not held. */
#define __requires_exclusive(...) \
__lock_annotate(exclusive_locks_required(__VA_ARGS__))
#define __requires_shared(...) \
__lock_annotate(shared_locks_required(__VA_ARGS__))
#define __requires_unlocked(...) \
__lock_annotate(locks_excluded(__VA_ARGS__))
/* Function should not be analyzed. */
#define __no_lock_analysis __lock_annotate(no_thread_safety_analysis)
/* Guard variables and structure members by lock. */
#define __guarded_by(x) __lock_annotate(guarded_by(x))
#define __pt_guarded_by(x) __lock_annotate(pt_guarded_by(x))
#endif /* !_SYS_CDEFS_H_ */