Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Sep 2014 18:34:31 +0000 (UTC)
From:      Ed Schouten <ed@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r270943 - in head: include lib/libstdthreads
Message-ID:  <201409011834.s81IYVUO086394@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <pthread.h> and
  <threads.h> 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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409011834.s81IYVUO086394>