Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 07 Jun 2012 06:34:20 +0000
From:      gmiller@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r237247 - soc2012/gmiller/locking-head/lib/libthr/thread
Message-ID:  <20120607063420.960A4106566B@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gmiller
Date: Thu Jun  7 06:34:19 2012
New Revision: 237247
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237247

Log:
  Implement _lock_profile_init(), _mutex_obtain_success(), and
  _mutex_obtain_failed().
  

Modified:
  soc2012/gmiller/locking-head/lib/libthr/thread/thr_init.c
  soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h
  soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c

Modified: soc2012/gmiller/locking-head/lib/libthr/thread/thr_init.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_init.c	Thu Jun  7 05:37:46 2012	(r237246)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_init.c	Thu Jun  7 06:34:19 2012	(r237247)
@@ -360,6 +360,8 @@
 		if (_thread_event_mask & TD_CREATE)
 			_thr_report_creation(curthread, curthread);
 	}
+
+	INIT_LOCK_PROFILING();
 }
 
 /*

Modified: soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h	Thu Jun  7 05:37:46 2012	(r237246)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h	Thu Jun  7 06:34:19 2012	(r237247)
@@ -106,6 +106,11 @@
 # define STATIC_LIB_REQUIRE(name) __asm (".globl " #name)
 #endif
 
+#define TIMESPEC_GT(left, right)                                              \
+	((left)->tv_sec > (right)->tv_sec ||				      \
+	    ((left)->tv_sec == (right)->tv_sec &&                             \
+	    (left)->tv_nsec > (right)->tv_nsec))
+
 #define	TIMESPEC_ADD(dst, src, val)				\
 	do { 							\
 		(dst)->tv_sec = (src)->tv_sec + (val)->tv_sec;	\
@@ -735,7 +740,7 @@
  */
 __BEGIN_DECLS
 int	_thr_setthreaded(int) __hidden;
-int	_mutex_cv_lock(struct pthread_mutex *, int count _PROFILE_PARMS)      \
+int	_mutex_cv_lock(struct pthread_mutex *, int count _PROFILE_PARMS)
 	    __hidden;
 int	_mutex_cv_unlock(struct pthread_mutex *, int *count) __hidden;
 int     _mutex_cv_attach(struct pthread_mutex *, int count) __hidden;
@@ -743,40 +748,33 @@
 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 *waittime, const char *, int)
+void	_mutex_obtain_failed(struct pthread_mutex *, struct timespec *waittime)
 	    __hidden;
 void	_mutex_obtain_success(struct pthread_mutex *,
 			      struct timespec *waittime, 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 *waittime,
-				    const char *file, int line)
-	    __hidden;
+	    struct timespec *waittime,
+	    const char *file, int line) __hidden;
 void	_rwlock_obtain_read_failed(struct pthread_rwlock *, 
-				   struct timespec *waittime,
-				   const char *file, int line)
-	    __hidden;
+	    struct timespec *waittime) __hidden;
 void	_rwlock_obtain_write_success(struct pthread_rwlock *,
-				     struct timespec *waittime,
-				     const char *file, int line)
-	     __hidden;
+	    struct timespec *waittime,
+	    const char *file, int line) __hidden;
 void	_rwlock_obtain_write_failed(struct pthread_rwlock *,
-				    struct timespec *waittime,
-				    const char *file, int line)
-	     __hidden;
+	    struct timespec *waittime) __hidden;
 void	_rwlock_release_read(struct pthread_rwlock *, struct timespec *)
-	     __hidden;
+	    __hidden;
 void	_rwlock_release_write(struct pthread_rwlock *, struct timespec *)
 	    __hidden;
 void	_mutex_release(struct pthread_mutex *, struct timespec *) __hidden;
 void	_spin_obtain_success(struct pthread_spinlock *,
-			     struct timespec *waittime,
-			     const char *file, int line) __hidden;
+	    struct timespec *waittime,
+	    const char *file, int line) __hidden;
 void	_spin_obtain_failed(struct pthread_spinlock *,
-			    struct timespec *waittime,
-			    const char *file, int line) __hidden;
+	    struct timespec *waittime) __hidden;
 void	_spin_release(struct pthread_spinlock *, struct timespec *) __hidden;
 void	_libpthread_init(struct pthread *) __hidden;
 struct pthread *_thr_alloc(struct pthread *) __hidden;
@@ -823,9 +821,9 @@
 void	_thr_signal_postfork_child(void) __hidden;
 void	_thr_try_gc(struct pthread *, struct pthread *) __hidden;
 int	_rtp_to_schedparam(const struct rtprio *rtp, int *policy,
-		struct sched_param *param) __hidden;
+	    struct sched_param *param) __hidden;
 int	_schedparam_to_rtp(int policy, const struct sched_param *param,
-		struct rtprio *rtp) __hidden;
+	    struct rtprio *rtp) __hidden;
 void	_thread_bp_create(void);
 void	_thread_bp_death(void);
 int	_sched_yield(void);
@@ -838,32 +836,35 @@
 
 #ifdef LOCK_PROFILING
 
+#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, line)
+		_mutex_obtain_failed(m, ts)
 #define		MUTEX_RELEASE(m, ts)	_mutex_release(m, ts)
 #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, file, line)
+		_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, file, line)
+		_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		SPIN_OBTAIN_SUCCESS(s, ts)                                   \
 		_spin_obtain_success(s, ts, file, line)
 #define		SPIN_OBTAIN_FAILED(s, ts)                                    \
-		_spin_obtain_failed(s, ts, file, line)
+		_spin_obtain_failed(s, ts)
 #define		SPIN_RELEASE(s, ts)                                          \
 		_spin_release(s, ts)
 
 #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)

Modified: soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c	Thu Jun  7 05:37:46 2012	(r237246)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c	Thu Jun  7 06:34:19 2012	(r237247)
@@ -28,26 +28,40 @@
 #ifdef LOCK_PROFILING
 
 #include <stdlib.h>
+#include <time.h>
 
 #include "thr_private.h"
 
 #define LOCK_PROF_HASH_SIZE (4096)
 
-struct lock_acquisition {
+struct acquisition {
 	const char *file;
 	int line;
-	SLIST_ENTRY(lock_acquisition) acq_next;
+	struct timespec acq_time;
+	int count;
+	int ref;
+	struct timespec waittime;
+	SLIST_ENTRY(acquisition) acq_next;
 };
 
-SLIST_HEAD(acq_head, lock_acquisition);
+SLIST_HEAD(acq_head, acquisition);
 
 struct acq_head mutex_hash[LOCK_PROF_HASH_SIZE];
 
-static struct lock_acquisition *
+void _lock_profile_init()
+{	
+	int i;
+
+	for (i = 0; i < LOCK_PROF_HASH_SIZE; i++) {
+		SLIST_INIT(&mutex_hash[i]);
+	}
+}
+
+static struct acquisition *
 mutex_lookup(struct pthread_mutex *m, const char *file, int line)
 {
 	u_int hash;
-	struct lock_acquisition *acq;
+	struct acquisition *acq;
 
 	hash = ((uintptr_t)file * 31 + line) & (LOCK_PROF_HASH_SIZE - 1);
 
@@ -57,7 +71,7 @@
 		}
 	}
 
-	acq = malloc(sizeof(struct lock_acquisition));
+	acq = malloc(sizeof(struct acquisition));
 	acq->file = file;
 	acq->line = line;
 
@@ -70,13 +84,37 @@
 _mutex_obtain_success(struct pthread_mutex *m, struct timespec *waittime,
 		      const char *file, int line)
 {
-	mutex_lookup(m, file, line);
+	struct pthread *curthread = _get_curthread();
+	struct acquisition *acq;
+
+	THR_CRITICAL_ENTER(curthread);
+
+	acq = mutex_lookup(m, file, line);
+	if (acq != NULL) {
+		acq->count++;
+		acq->ref++;
+		if (acq->ref == 1) {
+			clock_gettime(CLOCK_REALTIME, &acq->acq_time);
+			if (waittime->tv_sec != 0 || waittime->tv_nsec != 0) {
+				if (TIMESPEC_GT(&acq->acq_time, waittime)) {
+					TIMESPEC_SUB(&acq->waittime,
+					    &acq->acq_time, &acq->acq_time);
+				}
+			} else {
+				bzero(&acq->waittime, sizeof(acq->waittime));
+			}
+		}
+	}
+
+	THR_CRITICAL_LEAVE(curthread);
 }
 
 void
-_mutex_obtain_failed(struct pthread_mutex *m, struct timespec *waittime,
-		     const char *file, int line)
+_mutex_obtain_failed(struct pthread_mutex *m, struct timespec *waittime)
 {
+	if (waittime->tv_sec == 0 && waittime->tv_nsec == 0) {
+  		clock_gettime(CLOCK_REALTIME, waittime);
+	}
 }
 
 void
@@ -97,9 +135,7 @@
 }
 
 void
-_rwlock_obtain_read_failed(struct pthread_rwlock *l,
-			   struct timespec *waittime, const char *file,
-			   int line)
+_rwlock_obtain_read_failed(struct pthread_rwlock *l, struct timespec *waittime)
 {
 }
 
@@ -112,8 +148,7 @@
 
 void
 _rwlock_obtain_write_failed(struct pthread_rwlock *l,
-			    struct timespec *watitime, const char *file,
-			    int line)
+			    struct timespec *watitime)
 {
 }
 
@@ -134,8 +169,7 @@
 }
 
 void
-_spin_obtain_failed(struct pthread_spinlock *s, struct timespec *waittime,
-		    const char *file, int line)
+_spin_obtain_failed(struct pthread_spinlock *s, struct timespec *waittime)
 {
 }
 



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