Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 07 Jun 2012 23:33:08 +0000
From:      gmiller@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r237279 - soc2012/gmiller/locking-head/lib/libthr/thread
Message-ID:  <20120607233308.A884E1065679@hub.freebsd.org>

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

Log:
  Implement _mutex_release().
  

Modified:
  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_private.h
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h	Thu Jun  7 22:57:26 2012	(r237278)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_private.h	Thu Jun  7 23:33:07 2012	(r237279)
@@ -748,33 +748,29 @@
 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)
-	    __hidden;
-void	_mutex_obtain_success(struct pthread_mutex *,
-			      struct timespec *waittime, const char *, int)
+void	_mutex_obtain_failed(struct pthread_mutex *, struct timespec *)
 	    __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 *waittime,
-	    const char *file, int line) __hidden;
+	    struct timespec *wait_time, const char *file, int line) __hidden;
 void	_rwlock_obtain_read_failed(struct pthread_rwlock *, 
-	    struct timespec *waittime) __hidden;
+	    struct timespec *wait_time) __hidden;
 void	_rwlock_obtain_write_success(struct pthread_rwlock *,
-	    struct timespec *waittime,
-	    const char *file, int line) __hidden;
+	    struct timespec *wait_time, const char *file, int line) __hidden;
 void	_rwlock_obtain_write_failed(struct pthread_rwlock *,
-	    struct timespec *waittime) __hidden;
+	    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 *, struct timespec *) __hidden;
 void	_spin_obtain_success(struct pthread_spinlock *,
-	    struct timespec *waittime,
-	    const char *file, int line) __hidden;
+	    struct timespec *wait_time, const char *file, int line) __hidden;
 void	_spin_obtain_failed(struct pthread_spinlock *,
-	    struct timespec *waittime) __hidden;
+	    struct timespec *wait_time) __hidden;
 void	_spin_release(struct pthread_spinlock *, struct timespec *) __hidden;
 void	_libpthread_init(struct pthread *) __hidden;
 struct pthread *_thr_alloc(struct pthread *) __hidden;

Modified: soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c	Thu Jun  7 22:57:26 2012	(r237278)
+++ soc2012/gmiller/locking-head/lib/libthr/thread/thr_profile.c	Thu Jun  7 23:33:07 2012	(r237279)
@@ -29,26 +29,44 @@
 
 #include <stdlib.h>
 #include <time.h>
+#include <inttypes.h>
+#include <string.h>
 
 #include "thr_private.h"
 
 #define LOCK_PROF_HASH_SIZE (4096)
 
+struct acquisition_point {
+	SLIST_ENTRY(acquisition_point) acq_point_next;
+	const char 	*file;
+	int		line;
+	struct timespec	wait_max;
+	struct timespec	hold_max;
+	uintmax_t	contest_count;
+	struct timespec	wait_time;
+	struct timespec	hold_time;
+	int		acq_count;
+};
+
+SLIST_HEAD(acq_point_head, acquisition_point);
+
 struct acquisition {
-	const char *file;
-	int line;
-	struct timespec acq_time;
-	int count;
-	int ref;
-	struct timespec waittime;
-	SLIST_ENTRY(acquisition) acq_next;
+	LIST_ENTRY(acquisition) acq_next;
+	void		*lock;
+	const char	*file;
+	int		line;
+	struct timespec	acq_time;
+	int		count;
+	int		ref;
+	struct timespec	wait_time;
 };
 
-SLIST_HEAD(acq_head, acquisition);
+LIST_HEAD(acq_head, acquisition) acq_head = LIST_HEAD_INITIALIZER(acq_head);
 
-struct acq_head mutex_hash[LOCK_PROF_HASH_SIZE];
+struct acq_point_head mutex_hash[LOCK_PROF_HASH_SIZE];
 
-void _lock_profile_init()
+void
+_lock_profile_init()
 {	
 	int i;
 
@@ -58,30 +76,53 @@
 }
 
 static struct acquisition *
-mutex_lookup(struct pthread_mutex *m, const char *file, int line)
+mutex_lookup_acq(struct pthread_mutex *m, const char *file, int line)
 {
-	u_int hash;
 	struct acquisition *acq;
 
-	hash = ((uintptr_t)file * 31 + line) & (LOCK_PROF_HASH_SIZE - 1);
-
-	SLIST_FOREACH(acq, &mutex_hash[hash], acq_next) {
+	LIST_FOREACH(acq, &acq_head, acq_next) {
 		if (acq->file == file && acq->line == line) {
 			return acq;
 		}
 	}
 
 	acq = malloc(sizeof(struct acquisition));
+	bzero(acq, sizeof(*acq));
+	acq->lock = m;
 	acq->file = file;
 	acq->line = line;
 
-	SLIST_INSERT_HEAD(&mutex_hash[hash], acq, acq_next);
+	LIST_INSERT_HEAD(&acq_head, acq, acq_next);
+
+	return (acq);
+}
+
+static struct acquisition_point *
+mutex_lookup_acq_point(struct pthread_mutex *m, 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) {
+		if (acq_point->file == file && acq_point->line == line) {
+			return (acq_point);
+		}
+	}
+
+	acq_point = malloc(sizeof(struct acquisition_point));
+	bzero(acq_point, sizeof(*acq_point));
+	acq_point->file = file;
+	acq_point->line = line;
 
-	return acq;
+	SLIST_INSERT_HEAD(&mutex_hash[hash], acq_point, acq_point_next);
+
+	return (acq_point);
 }
 
 void
-_mutex_obtain_success(struct pthread_mutex *m, struct timespec *waittime,
+_mutex_obtain_success(struct pthread_mutex *m, struct timespec *wait_time,
 		      const char *file, int line)
 {
 	struct pthread *curthread = _get_curthread();
@@ -89,19 +130,20 @@
 
 	THR_CRITICAL_ENTER(curthread);
 
-	acq = mutex_lookup(m, file, line);
+	acq = mutex_lookup_acq(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,
+			if (wait_time->tv_sec != 0 ||
+			    wait_time->tv_nsec != 0) {
+				if (TIMESPEC_GT(&acq->acq_time, wait_time)) {
+					TIMESPEC_SUB(&acq->wait_time,
 					    &acq->acq_time, &acq->acq_time);
 				}
 			} else {
-				bzero(&acq->waittime, sizeof(acq->waittime));
+				bzero(&acq->wait_time, sizeof(acq->wait_time));
 			}
 		}
 	}
@@ -110,16 +152,69 @@
 }
 
 void
-_mutex_obtain_failed(struct pthread_mutex *m, struct timespec *waittime)
+_mutex_obtain_failed(struct pthread_mutex *m, struct timespec *wait_time)
 {
-	if (waittime->tv_sec == 0 && waittime->tv_nsec == 0) {
-  		clock_gettime(CLOCK_REALTIME, waittime);
+	if (wait_time->tv_sec == 0 && wait_time->tv_nsec == 0) {
+  		clock_gettime(CLOCK_REALTIME, wait_time);
 	}
 }
 
 void
-_mutex_release(struct pthread_mutex *m, struct timespec *waittime)
+_mutex_release(struct pthread_mutex *m, struct timespec *wait_time)
 {
+	struct pthread *curthread = _get_curthread();
+	struct acquisition *acq;
+	struct acquisition_point *acq_point;
+	struct timespec current_time;
+	struct timespec hold_time;
+
+	THR_CRITICAL_ENTER(curthread);
+
+	LIST_FOREACH(acq, &acq_head, acq_next) {
+		if (acq->lock == m) {
+			break;
+		}
+	}
+
+	if (acq != NULL) {
+		acq->ref--;
+		if (acq->ref == 0) {
+			acq_point = mutex_lookup_acq_point(m, acq->file,
+			    acq->line);
+			clock_gettime(CLOCK_REALTIME, &current_time);
+			if (acq_point != NULL &&
+			    TIMESPEC_GT(&acq->acq_time, &current_time)) {
+				TIMESPEC_SUB(&hold_time, &current_time,
+				    &acq->acq_time);
+				if (TIMESPEC_GT(&hold_time,
+				    &acq_point->hold_max)) {
+					memcpy(&acq_point->hold_max,
+					    &hold_time,
+					    sizeof(struct timespec));
+				}
+				if (TIMESPEC_GT(wait_time,
+				    &acq_point->wait_max)) {
+					memcpy(&acq_point->wait_max,
+					    wait_time,
+					    sizeof(struct timespec));
+				}
+				TIMESPEC_ADD(&acq_point->hold_time,
+				    &acq_point->hold_time, &hold_time);
+				TIMESPEC_ADD(&acq_point->wait_time,
+				    &acq_point->wait_time, wait_time);
+				acq_point->acq_count += acq->count;
+				if (wait_time->tv_sec != 0 ||
+				    wait_time->tv_nsec != 0) {
+					acq_point->contest_count++;
+				}
+			}
+		}
+
+		LIST_REMOVE(acq, acq_next);
+		free(acq);
+	}
+	    
+	THR_CRITICAL_LEAVE(curthread);
 }
 
 void
@@ -129,19 +224,20 @@
 
 void
 _rwlock_obtain_read_success(struct pthread_rwlock *l,
-			    struct timespec *waittime, const char *file,
+			    struct timespec *wait_time, const char *file,
 			    int line)
 {
 }
 
 void
-_rwlock_obtain_read_failed(struct pthread_rwlock *l, struct timespec *waittime)
+_rwlock_obtain_read_failed(struct pthread_rwlock *l,
+    struct timespec *wait_time)
 {
 }
 
 void
 _rwlock_obtain_write_success(struct pthread_rwlock *l,
-			     struct timespec *waittime, const char *file,
+			     struct timespec *wait_time, const char *file,
 			     int line)
 {
 }
@@ -153,28 +249,28 @@
 }
 
 void
-_rwlock_release_read(struct pthread_rwlock *l, struct timespec *waittime)
+_rwlock_release_read(struct pthread_rwlock *l, struct timespec *wait_time)
 {
 }
 
 void
-_rwlock_release_write(struct pthread_rwlock *l, struct timespec *waittime)
+_rwlock_release_write(struct pthread_rwlock *l, struct timespec *wait_time)
 {
 }
 
 void
-_spin_obtain_success(struct pthread_spinlock *s, struct timespec *waittime,
+_spin_obtain_success(struct pthread_spinlock *s, struct timespec *wait_time,
 		     const char *file, int line)
 {
 }
 
 void
-_spin_obtain_failed(struct pthread_spinlock *s, struct timespec *waittime)
+_spin_obtain_failed(struct pthread_spinlock *s, struct timespec *wait_time)
 {
 }
 
 void
-_spin_release(struct pthread_spinlock *s, struct timespec *waittime)
+_spin_release(struct pthread_spinlock *s, struct timespec *wait_time)
 {
 }
 



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