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, ¤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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120616053141.AEAC61065672>