Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Jun 2012 05:31:41 +0000
From:      gmiller@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r237794 - in soc2012/gmiller/locking-head: include lib/libthr/thread
Message-ID:  <20120616053141.AEAC61065672@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gmiller
Date: Sat Jun 16 05:31:40 2012
New Revision: 237794
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237794

Log:
  Implement profiling of read/write locks.
  

Modified:
  soc2012/gmiller/locking-head/include/pthread.h
  soc2012/gmiller/locking-head/lib/libthr/thread/thr_exit.c
  soc2012/gmiller/locking-head/lib/libthr/thread/thr_mutex.c
  soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h
  soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c
  soc2012/gmiller/locking-head/lib/libthr/thread/thr_rwlock.c

Modified: soc2012/gmiller/locking-head/include/pthread.h
==============================================================================
--- soc2012/gmiller/locking-head/include/pthread.h	Sat Jun 16 04:41:35 2012	(r237793)
+++ soc2012/gmiller/locking-head/include/pthread.h	Sat Jun 16 05:31:40 2012	(r237794)
@@ -336,6 +336,8 @@
 int		_pthread_rwlock_wrlock_profiled(pthread_rwlock_t *,
 						const char *,
 						int);
+int		_pthread_rwlock_unlock_profiled(pthread_rwlock_t *,
+						const char *, int);
 int		_pthread_spin_lock_profiled(pthread_spinlock_t *,
 					    const char *,
 					    int);

Modified: soc2012/gmiller/locking-head/lib/libthr/thread/thr_exit.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_exit.c	Sat Jun 16 04:41:35 2012	(r237793)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_exit.c	Sat Jun 16 05:31:40 2012	(r237794)
@@ -263,8 +263,6 @@
 {
 	struct pthread *curthread = _get_curthread();
 
-	LOCK_PROFILE_EXIT_THREAD(curthread);
-
 	/* Check if there is thread specific data: */
 	if (curthread->specific != NULL) {
 		/* Run the thread-specific data destructors: */

Modified: soc2012/gmiller/locking-head/lib/libthr/thread/thr_mutex.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_mutex.c	Sat Jun 16 04:41:35 2012	(r237793)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_mutex.c	Sat Jun 16 05:31:40 2012	(r237794)
@@ -357,11 +357,11 @@
 	ret = _thr_umutex_trylock(&m->m_lock, id);
 	if (__predict_true(ret == 0)) {
 		ENQUEUE_MUTEX(curthread, m);
-		MUTEX_OBTAIN_SUCCESS(m, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(m, &waittime);
 	} else if (m->m_owner == curthread) {
 		ret = mutex_self_trylock(m _PROFILE_PASS);
 	} else {
-		MUTEX_OBTAIN_FAILED(m, &waittime);
+		LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 	}
 
 	if (ret && (m->m_flags & PMUTEX_FLAG_PRIVATE))
@@ -405,7 +405,7 @@
 	if (m->m_owner == curthread)
 		return mutex_self_lock(m, abstime _PROFILE_PASS);
 
-	MUTEX_OBTAIN_FAILED(m, &waittime);
+	LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 
 	id = TID(curthread);
 	/*
@@ -460,7 +460,7 @@
 done:
 	if (ret == 0) {
 		ENQUEUE_MUTEX(curthread, m);
-		MUTEX_OBTAIN_SUCCESS(m, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(m, &waittime);
 	}
 
 	return (ret);
@@ -483,7 +483,7 @@
 		ENQUEUE_MUTEX(curthread, m);
 		ret = 0;
 
-		MUTEX_OBTAIN_SUCCESS(m, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(m, &waittime);
 	} else {
 		ret = mutex_lock_sleep(curthread, m, abstime _PROFILE_PASS);
 	}
@@ -653,9 +653,9 @@
 	}
 
 	if (ret == 0) {
-		MUTEX_OBTAIN_SUCCESS(m, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(m, &waittime);
 	} else {
-		MUTEX_OBTAIN_FAILED(m, &waittime);
+		LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 	}
 
 	return (ret);
@@ -675,7 +675,7 @@
 	switch (PMUTEX_TYPE(m->m_flags)) {
 	case PTHREAD_MUTEX_ERRORCHECK:
 	case PTHREAD_MUTEX_ADAPTIVE_NP:
-		MUTEX_OBTAIN_FAILED(m, &waittime);
+		LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 
 		if (abstime) {
 			if (abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
@@ -701,7 +701,7 @@
 		 * What SS2 define as a 'normal' mutex.  Intentionally
 		 * deadlock on attempts to get a lock you already own.
 		 */
-		MUTEX_OBTAIN_FAILED(m, &waittime);
+		LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 
 		ret = 0;
 		if (abstime) {
@@ -729,7 +729,7 @@
 			ret = 0;
 		} else {
 			ret = EAGAIN;
-			MUTEX_OBTAIN_FAILED(m, &waittime);
+			LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 		}
 
 		break;
@@ -739,7 +739,7 @@
 	}
 
 	if (ret == 0) {
-		MUTEX_OBTAIN_SUCCESS(m, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(m, &waittime);
 	}
 
 	return (ret);
@@ -771,10 +771,10 @@
 		m->m_count--;
 
 		if (m->m_count == 0) {
-			MUTEX_RELEASE(m);
+			LOCK_PROFILE_RELEASE(m);
 		}
 	} else {
-		MUTEX_RELEASE(m);
+		LOCK_PROFILE_RELEASE(m);
 
 		if ((m->m_flags & PMUTEX_FLAG_DEFERED) != 0) {
 			defered = 1;

Modified: soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h	Sat Jun 16 04:41:35 2012	(r237793)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h	Sat Jun 16 05:31:40 2012	(r237794)
@@ -749,25 +749,11 @@
 int     _mutex_owned(struct pthread *, const struct pthread_mutex *) __hidden;
 int	_mutex_reinit(pthread_mutex_t *) __hidden;
 void	_mutex_fork(struct pthread *curthread) __hidden;
-void	_mutex_obtain_failed(struct pthread_mutex *, struct timespec *,
-			     const char *) __hidden;
-void	_mutex_obtain_success(struct pthread_mutex *, struct timespec *,
-	    const char *, int) __hidden;
 void	_lock_profile_init(void) __hidden;
-void	_lock_profile_exit_thread(struct pthread *curthread) __hidden;
-void	_rwlock_obtain_read_success(struct pthread_rwlock *,
-	    struct timespec *wait_time, const char *file, int line) __hidden;
-void	_rwlock_obtain_read_failed(struct pthread_rwlock *, 
-	    struct timespec *wait_time) __hidden;
-void	_rwlock_obtain_write_success(struct pthread_rwlock *,
-	    struct timespec *wait_time, const char *file, int line) __hidden;
-void	_rwlock_obtain_write_failed(struct pthread_rwlock *,
-	    struct timespec *wait_time) __hidden;
-void	_rwlock_release_read(struct pthread_rwlock *, struct timespec *)
-	    __hidden;
-void	_rwlock_release_write(struct pthread_rwlock *, struct timespec *)
-	    __hidden;
-void	_mutex_release(struct pthread_mutex *, const char *file) __hidden;
+void	_lock_profile_obtain_failed(struct timespec *, const char *) __hidden;
+void	_lock_profile_obtain_success(void *, struct timespec *, const char *,
+				     int) __hidden;
+void	_lock_profile_release(void *, const char *file) __hidden;
 void	_spin_obtain_success(struct pthread_spinlock *,
 	    struct timespec *wait_time, const char *file, int line) __hidden;
 void	_spin_obtain_failed(struct pthread_spinlock *,
@@ -835,23 +821,11 @@
 
 #define		INIT_LOCK_PROFILING()                                        \
 		_lock_profile_init()
-#define		LOCK_PROFILE_EXIT_THREAD(t)                                  \
-		_lock_profile_exit_thread(t)
-#define		MUTEX_OBTAIN_SUCCESS(m, ts)                                  \
-		_mutex_obtain_success(m, ts, file, line)
-#define		MUTEX_OBTAIN_FAILED(m, ts)                                   \
-		_mutex_obtain_failed(m, ts, file)
-#define		MUTEX_RELEASE(m)	_mutex_release(m, file)
-#define		RWLOCK_OBTAIN_READ_SUCCESS(l, ts)                            \
-		_rwlock_obtain_read_success(l, ts, file, line)
-#define		RWLOCK_OBTAIN_READ_FAILED(l, ts)                             \
-		_rwlock_obtain_read_failed(l, ts)
-#define		RWLOCK_OBTAIN_WRITE_SUCCESS(l, ts)                           \
-		_rwlock_obtain_write_success(l, ts, file, line)
-#define		RWLOCK_OBTAIN_WRITE_FAILED(l, ts)                            \
-		_rwlock_obtain_write_failed(l, ts)
-#define		RWLOCK_RELEASE_READ(l, ts)	_rwlock_release_read(l, ts)
-#define		RWLOCK_RELEASE_WRITE(l, ts)	_rwlock_release_write(l, ts)
+#define		LOCK_PROFILE_OBTAIN_SUCCESS(l, ts)                           \
+		_lock_profile_obtain_success(l, ts, file, line)
+#define		LOCK_PROFILE_OBTAIN_FAILED(ts)                               \
+		_lock_profile_obtain_failed(ts, file)
+#define		LOCK_PROFILE_RELEASE(l)	_lock_profile_release(l, file)
 #define		SPIN_OBTAIN_SUCCESS(s, ts)                                   \
 		_spin_obtain_success(s, ts, file, line)
 #define		SPIN_OBTAIN_FAILED(s, ts)                                    \
@@ -862,16 +836,9 @@
 #else
 
 #define		INIT_LOCK_PROFILING()			do { } while (0)
-#define		LOCK_PROFILE_EXIT_THREAD(t)		do { } while (0)
-#define		MUTEX_OBTAIN_SUCCESS(m, ts)		do { } while (0)
-#define		MUTEX_OBTAIN_FAILED(m, ts)		do { } while (0)
-#define		MUTEX_RELEASE(m)			do { } while (0)
-#define		RWLOCK_OBTAIN_READ_SUCCESS(l, ts)	do { } while (0)
-#define		RWLOCK_OBTAIN_READ_FAILED(l, ts)	do { } while (0)
-#define		RWLOCK_OBTAIN_WRITE_SUCCESS(l, ts)	do { } while (0)
-#define		RWLOCK_OBTAIN_WRITE_FAILED(l, ts)	do { } while (0)
-#define		RWLOCK_RELEASE_READ(l, ts)		do { } while (0)
-#define		RWLOCK_RELEASE_WRITE(l, ts)		do { } while (0)
+#define		LOCK_PROFILE_OBTAIN_SUCCESS(l, ts)	do { } while (0)
+#define		LOCK_PROFILE_OBTAIN_FAILED(ts)		do { } while (0)
+#define		LOCK_PROFILE_RELEASE(l)			do { } while (0)
 #define		SPIN_OBTAIN_SUCCESS(s, ts)		do { } while (0)
 #define		SPIN_OBTAIN_FAILED(s, ts)		do { } while (0)
 #define		SPIN_RELEASE(s, ts)			do { } while (0)

Modified: soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c	Sat Jun 16 04:41:35 2012	(r237793)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c	Sat Jun 16 05:31:40 2012	(r237794)
@@ -65,7 +65,7 @@
 static LIST_HEAD(acq_head, acquisition) acq_head =
      LIST_HEAD_INITIALIZER(acq_head);
 
-struct acq_point_head mutex_hash[LOCK_PROF_HASH_SIZE];
+static struct acq_point_head lock_hash[LOCK_PROF_HASH_SIZE];
 
 struct _pthread_statistics_private {
 	u_int		hash;
@@ -80,14 +80,14 @@
 	int i;
 
 	for (i = 0; i < LOCK_PROF_HASH_SIZE; i++) {
-		SLIST_INIT(&mutex_hash[i]);
+		SLIST_INIT(&lock_hash[i]);
 	}
 
 	lockprof_enabled = 1;
 }
 
 static struct acquisition *
-mutex_lookup_acq(struct pthread_mutex *m, const char *file, int line)
+lookup_acq(void *lock, const char *file, int line)
 {
 	struct acquisition *acq;
 
@@ -98,7 +98,7 @@
 	}
 
 	acq = calloc(1, sizeof(*acq));
-	acq->lock = m;
+	acq->lock = lock;
 	acq->file = file;
 	acq->line = line;
 
@@ -108,14 +108,14 @@
 }
 
 static struct acquisition_point *
-mutex_lookup_acq_point(struct pthread_mutex *m, const char *file, int line)
+lookup_acq_point(const char *file, int line)
 {
 	u_int hash;
 	struct acquisition_point *acq_point;
 
 	hash = ((uintptr_t)file * 31 + line) & (LOCK_PROF_HASH_SIZE - 1);
 
-	SLIST_FOREACH(acq_point, &mutex_hash[hash], acq_point_next) {
+	SLIST_FOREACH(acq_point, &lock_hash[hash], acq_point_next) {
 		if (acq_point->file == file && acq_point->line == line) {
 			return (acq_point);
 		}
@@ -125,14 +125,14 @@
 	acq_point->file = file;
 	acq_point->line = line;
 
-	SLIST_INSERT_HEAD(&mutex_hash[hash], acq_point, acq_point_next);
+	SLIST_INSERT_HEAD(&lock_hash[hash], acq_point, acq_point_next);
 
 	return (acq_point);
 }
 
 void
-_mutex_obtain_success(struct pthread_mutex *m, struct timespec *wait_time,
-		      const char *file, int line)
+_lock_profile_obtain_success(void *lock, struct timespec *wait_time,
+			     const char *file, int line)
 {
 	struct pthread *curthread = _get_curthread();
 	struct acquisition *acq;
@@ -143,7 +143,7 @@
 
 	THR_CRITICAL_ENTER(curthread);
 
-	acq = mutex_lookup_acq(m, file, line);
+	acq = lookup_acq(lock, file, line);
 	if (acq != NULL) {
 		acq->count++;
 		acq->ref++;
@@ -165,8 +165,7 @@
 }
 
 void
-_mutex_obtain_failed(struct pthread_mutex *m, struct timespec *wait_time,
-		     const char *file)
+_lock_profile_obtain_failed(struct timespec *wait_time, const char *file)
 {
 	if (file == NULL || !lockprof_enabled) {
 		return;
@@ -178,7 +177,7 @@
 }
 
 void
-_mutex_release(struct pthread_mutex *m, const char *file)
+_lock_profile_release(void *lock, const char *file)
 {
 	struct pthread *curthread = _get_curthread();
 	struct acquisition *acq;
@@ -193,7 +192,7 @@
 	THR_CRITICAL_ENTER(curthread);
 
 	LIST_FOREACH(acq, &acq_head, acq_next) {
-		if (acq->lock == m) {
+		if (acq->lock == lock) {
 			break;
 		}
 	}
@@ -201,8 +200,7 @@
 	if (acq != NULL) {
 		acq->ref--;
 		if (acq->ref == 0) {
-			acq_point = mutex_lookup_acq_point(m, acq->file,
-			    acq->line);
+			acq_point = lookup_acq_point(acq->file, acq->line);
 			clock_gettime(CLOCK_REALTIME, &current_time);
 			if (acq_point != NULL) {
 				bzero(&hold_time, sizeof(hold_time));
@@ -243,47 +241,6 @@
 }
 
 void
-_lock_profile_exit_thread(struct pthread *t)
-{
-}
-
-void
-_rwlock_obtain_read_success(struct pthread_rwlock *l,
-			    struct timespec *wait_time, const char *file,
-			    int line)
-{
-}
-
-void
-_rwlock_obtain_read_failed(struct pthread_rwlock *l,
-			   struct timespec *wait_time)
-{
-}
-
-void
-_rwlock_obtain_write_success(struct pthread_rwlock *l,
-			     struct timespec *wait_time, const char *file,
-			     int line)
-{
-}
-
-void
-_rwlock_obtain_write_failed(struct pthread_rwlock *l,
-			    struct timespec *watitime)
-{
-}
-
-void
-_rwlock_release_read(struct pthread_rwlock *l, struct timespec *wait_time)
-{
-}
-
-void
-_rwlock_release_write(struct pthread_rwlock *l, struct timespec *wait_time)
-{
-}
-
-void
 _spin_obtain_success(struct pthread_spinlock *s, struct timespec *wait_time,
 		     const char *file, int line)
 {
@@ -312,7 +269,7 @@
 				break;
 			} else {
 				stats->_pvt->last_record =
-				    SLIST_FIRST(&mutex_hash[stats->_pvt->hash]);
+				    SLIST_FIRST(&lock_hash[stats->_pvt->hash]);
 				stats->_pvt->hash++;
 			}
 		} else {

Modified: soc2012/gmiller/locking-head/lib/libthr/thread/thr_rwlock.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_rwlock.c	Sat Jun 16 04:41:35 2012	(r237793)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_rwlock.c	Sat Jun 16 05:31:40 2012	(r237794)
@@ -83,6 +83,9 @@
 int	_pthread_rwlock_trywrlock_profiled(pthread_rwlock_t *rwlock,
 					   const char *file,
 					   int line);
+int	_pthread_rwlock_unlock_profiled(pthread_rwlock_t *rwlock,
+					const char *file,
+					int line);
 
 #endif
 
@@ -183,12 +186,12 @@
 	if (ret == 0) {
 		curthread->rdlock_count++;
 
-		RWLOCK_OBTAIN_READ_SUCCESS(*rwlock, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(*rwlock, &waittime);
 
 		return (ret);
 	}
 
-	RWLOCK_OBTAIN_READ_FAILED(*rwlock, &waittime);
+	LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 
 	if (__predict_false(abstime && 
 		(abstime->tv_nsec >= 1000000000 || abstime->tv_nsec < 0)))
@@ -208,7 +211,7 @@
 	}
 	if (ret == 0) {
 		curthread->rdlock_count++;
-		RWLOCK_OBTAIN_READ_SUCCESS(*rwlock, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(*rwlock, &waittime);
 	}
 
 	return (ret);
@@ -291,9 +294,9 @@
 	ret = _thr_rwlock_tryrdlock(&prwlock->lock, flags);
 	if (ret == 0) {
 		curthread->rdlock_count++;
-		RWLOCK_OBTAIN_READ_SUCCESS(*rwlock, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(*rwlock, &waittime);
 	} else {
-		RWLOCK_OBTAIN_READ_FAILED(*rwlock, &waittime);
+		LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 	}
 	return (ret);
 }
@@ -324,9 +327,9 @@
 	ret = _thr_rwlock_trywrlock(&prwlock->lock);
 	if (ret == 0) {
 		prwlock->owner = curthread;
-		RWLOCK_OBTAIN_WRITE_SUCCESS(*rwlock, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(*rwlock, &waittime);
 	} else {
-		RWLOCK_OBTAIN_WRITE_FAILED(*rwlock, &waittime);
+		LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 	}
 	return (ret);
 }
@@ -354,12 +357,12 @@
 	if (ret == 0) {
 		prwlock->owner = curthread;
 
-		RWLOCK_OBTAIN_WRITE_SUCCESS(*rwlock, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(*rwlock, &waittime);
 
 		return (ret);
 	}
 
-	RWLOCK_OBTAIN_WRITE_FAILED(*rwlock, &waittime);
+	LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 
 	if (__predict_false(abstime && 
 		(abstime->tv_nsec >= 1000000000 || abstime->tv_nsec < 0)))
@@ -385,9 +388,9 @@
 	}
 
 	if (ret == 0) {
-		RWLOCK_OBTAIN_WRITE_SUCCESS(*rwlock, &waittime);
+		LOCK_PROFILE_OBTAIN_SUCCESS(*rwlock, &waittime);
 	} else {
-		RWLOCK_OBTAIN_WRITE_FAILED(*rwlock, &waittime);
+		LOCK_PROFILE_OBTAIN_FAILED(&waittime);
 	}
 
 	return (ret);
@@ -427,17 +430,21 @@
 }
 
 int
-_pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
+_pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+#ifdef LOCK_PROFILING
+{
+	return (_pthread_rwlock_unlock_profiled(rwlock, NULL, 0));
+}
+
+int
+_pthread_rwlock_unlock_profiled(pthread_rwlock_t *rwlock, const char *file,
+				int line)
+#endif
 {
 	struct pthread *curthread = _get_curthread();
 	pthread_rwlock_t prwlock;
 	int ret;
 	int32_t state;
-#ifdef LOCK_PROFILING
-	struct timespec waittime;
-
-	bzero(&waittime, sizeof(waittime));
-#endif
 	prwlock = *rwlock;
 
 	if (__predict_false(prwlock <= THR_RWLOCK_DESTROYED))
@@ -453,9 +460,10 @@
 	ret = _thr_rwlock_unlock(&prwlock->lock);
 	if (ret == 0 && (state & URWLOCK_WRITE_OWNER) == 0) {
 		curthread->rdlock_count--;
-		RWLOCK_RELEASE_READ(*rwlock, &waittime);
-	} else if (ret == 0) {
-		RWLOCK_RELEASE_WRITE(*rwlock, &waittime);
+	}
+
+	if (ret == 0) {
+		LOCK_PROFILE_RELEASE(*rwlock);
 	}
 
 	return (ret);



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