From owner-svn-src-head@FreeBSD.ORG Mon Sep 1 18:34:31 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id B68666A0; Mon, 1 Sep 2014 18:34:31 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A150B1FCE; Mon, 1 Sep 2014 18:34:31 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s81IYVp0086398; Mon, 1 Sep 2014 18:34:31 GMT (envelope-from ed@FreeBSD.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s81IYVUO086394; Mon, 1 Sep 2014 18:34:31 GMT (envelope-from ed@FreeBSD.org) Message-Id: <201409011834.s81IYVUO086394@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: ed set sender to ed@FreeBSD.org using -f From: Ed Schouten Date: Mon, 1 Sep 2014 18:34:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r270943 - in head: include lib/libstdthreads X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Sep 2014 18:34:31 -0000 Author: ed Date: Mon Sep 1 18:34:30 2014 New Revision: 270943 URL: http://svnweb.freebsd.org/changeset/base/270943 Log: Add lock annotations to the header files of our threading libraries. This change extends all of the functions present in the and headers to have lock annotations. This will allow Clang to warn about the following: - Locking a function twice, - Unlocking a function without a mutex being locked, - Forgetting to unlock a mutex before returning, - Destroying or reinitializing a mutex that is currenty locked, - Using an unlocked mutex in combination with a condition variable. Enabling these annotations already allowed me to catch a bug in one of our userspace tools (r270749). Modified: head/include/pthread.h head/lib/libstdthreads/threads.h Modified: head/include/pthread.h ============================================================================== --- head/include/pthread.h Mon Sep 1 18:28:11 2014 (r270942) +++ head/include/pthread.h Mon Sep 1 18:34:30 2014 (r270943) @@ -193,8 +193,10 @@ int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *); int pthread_cond_signal(pthread_cond_t *); int pthread_cond_timedwait(pthread_cond_t *, - pthread_mutex_t *, const struct timespec *); -int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); + pthread_mutex_t *__mutex, const struct timespec *) + __requires_exclusive(*__mutex); +int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *__mutex) + __requires_exclusive(*__mutex); int pthread_create(pthread_t *, const pthread_attr_t *, void *(*) (void *), void *); int pthread_detach(pthread_t); @@ -213,27 +215,42 @@ int pthread_mutexattr_getpshared(const int pthread_mutexattr_gettype(pthread_mutexattr_t *, int *); int pthread_mutexattr_settype(pthread_mutexattr_t *, int); int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); -int pthread_mutex_destroy(pthread_mutex_t *); -int pthread_mutex_init(pthread_mutex_t *, - const pthread_mutexattr_t *); -int pthread_mutex_lock(pthread_mutex_t *); -int pthread_mutex_trylock(pthread_mutex_t *); -int pthread_mutex_timedlock(pthread_mutex_t *, - const struct timespec *); -int pthread_mutex_unlock(pthread_mutex_t *); +int pthread_mutex_destroy(pthread_mutex_t *__mutex) + __requires_unlocked(*__mutex); +int pthread_mutex_init(pthread_mutex_t *__mutex, + const pthread_mutexattr_t *) + __requires_unlocked(*__mutex); +int pthread_mutex_lock(pthread_mutex_t *__mutex) + __locks_exclusive(*__mutex); +int pthread_mutex_trylock(pthread_mutex_t *__mutex) + __trylocks_exclusive(0, *__mutex); +int pthread_mutex_timedlock(pthread_mutex_t *__mutex, + const struct timespec *) + __trylocks_exclusive(0, *__mutex); +int pthread_mutex_unlock(pthread_mutex_t *__mutex) + __unlocks(*__mutex); int pthread_once(pthread_once_t *, void (*) (void)); -int pthread_rwlock_destroy(pthread_rwlock_t *); -int pthread_rwlock_init(pthread_rwlock_t *, - const pthread_rwlockattr_t *); -int pthread_rwlock_rdlock(pthread_rwlock_t *); -int pthread_rwlock_timedrdlock(pthread_rwlock_t *, - const struct timespec *); -int pthread_rwlock_timedwrlock(pthread_rwlock_t *, - const struct timespec *); -int pthread_rwlock_tryrdlock(pthread_rwlock_t *); -int pthread_rwlock_trywrlock(pthread_rwlock_t *); -int pthread_rwlock_unlock(pthread_rwlock_t *); -int pthread_rwlock_wrlock(pthread_rwlock_t *); +int pthread_rwlock_destroy(pthread_rwlock_t *__rwlock) + __requires_unlocked(*__rwlock); +int pthread_rwlock_init(pthread_rwlock_t *__rwlock, + const pthread_rwlockattr_t *) + __requires_unlocked(*__rwlock); +int pthread_rwlock_rdlock(pthread_rwlock_t *__rwlock) + __locks_shared(*__rwlock); +int pthread_rwlock_timedrdlock(pthread_rwlock_t *__rwlock, + const struct timespec *) + __trylocks_shared(0, *__rwlock); +int pthread_rwlock_timedwrlock(pthread_rwlock_t *__rwlock, + const struct timespec *) + __trylocks_exclusive(0, *__rwlock); +int pthread_rwlock_tryrdlock(pthread_rwlock_t *__rwlock) + __trylocks_shared(0, *__rwlock); +int pthread_rwlock_trywrlock(pthread_rwlock_t *__rwlock) + __trylocks_exclusive(0, *__rwlock); +int pthread_rwlock_unlock(pthread_rwlock_t *__rwlock) + __unlocks(*__rwlock); +int pthread_rwlock_wrlock(pthread_rwlock_t *__rwlock) + __locks_exclusive(*__rwlock); int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *, int *); @@ -245,11 +262,16 @@ int pthread_rwlockattr_setpshared(pthre pthread_t pthread_self(void); int pthread_setspecific(pthread_key_t, const void *); -int pthread_spin_init(pthread_spinlock_t *, int); -int pthread_spin_destroy(pthread_spinlock_t *); -int pthread_spin_lock(pthread_spinlock_t *); -int pthread_spin_trylock(pthread_spinlock_t *); -int pthread_spin_unlock(pthread_spinlock_t *); +int pthread_spin_init(pthread_spinlock_t *__spin, int) + __requires_unlocked(*__spin); +int pthread_spin_destroy(pthread_spinlock_t *__spin) + __requires_unlocked(*__spin); +int pthread_spin_lock(pthread_spinlock_t *__spin) + __locks_exclusive(*__spin); +int pthread_spin_trylock(pthread_spinlock_t *__spin) + __trylocks_exclusive(0, *__spin); +int pthread_spin_unlock(pthread_spinlock_t *__spin) + __unlocks(*__spin); int pthread_cancel(pthread_t); int pthread_setcancelstate(int, int *); int pthread_setcanceltype(int, int *); Modified: head/lib/libstdthreads/threads.h ============================================================================== --- head/lib/libstdthreads/threads.h Mon Sep 1 18:28:11 2014 (r270942) +++ head/lib/libstdthreads/threads.h Mon Sep 1 18:34:30 2014 (r270943) @@ -79,15 +79,24 @@ int cnd_broadcast(cnd_t *); void cnd_destroy(cnd_t *); int cnd_init(cnd_t *); int cnd_signal(cnd_t *); -int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict, - const struct timespec *__restrict); -int cnd_wait(cnd_t *, mtx_t *); -void mtx_destroy(mtx_t *); -int mtx_init(mtx_t *, int); -int mtx_lock(mtx_t *); -int mtx_timedlock(mtx_t *__restrict, const struct timespec *__restrict); -int mtx_trylock(mtx_t *); -int mtx_unlock(mtx_t *); +int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict __mtx, + const struct timespec *__restrict) + __requires_exclusive(*__mtx); +int cnd_wait(cnd_t *, mtx_t *__mtx) + __requires_exclusive(*__mtx); +void mtx_destroy(mtx_t *__mtx) + __requires_unlocked(*__mtx); +int mtx_init(mtx_t *__mtx, int) + __requires_unlocked(*__mtx); +int mtx_lock(mtx_t *__mtx) + __locks_exclusive(*__mtx); +int mtx_timedlock(mtx_t *__restrict __mtx, + const struct timespec *__restrict) + __trylocks_exclusive(thrd_success, *__mtx); +int mtx_trylock(mtx_t *__mtx) + __trylocks_exclusive(thrd_success, *__mtx); +int mtx_unlock(mtx_t *__mtx) + __unlocks(*__mtx); int thrd_create(thrd_t *, thrd_start_t, void *); thrd_t thrd_current(void); int thrd_detach(thrd_t);