socsvn commit: r237794 - in soc2012/gmiller/locking-head: include
lib/libthr/thread
gmiller at FreeBSD.org
gmiller at FreeBSD.org
Sat Jun 16 05:31:43 UTC 2012
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, ¤t_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);
More information about the svn-soc-all
mailing list