socsvn commit: r237279 -
soc2012/gmiller/locking-head/lib/libthr/thread
gmiller at FreeBSD.org
gmiller at FreeBSD.org
Thu Jun 7 23:33:10 UTC 2012
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, ¤t_time);
+ if (acq_point != NULL &&
+ TIMESPEC_GT(&acq->acq_time, ¤t_time)) {
+ TIMESPEC_SUB(&hold_time, ¤t_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)
{
}
More information about the svn-soc-all
mailing list