diff options
| author | Mateusz Guzik <mjg@FreeBSD.org> | 2017-02-05 03:26:34 +0000 |
|---|---|---|
| committer | Mateusz Guzik <mjg@FreeBSD.org> | 2017-02-05 03:26:34 +0000 |
| commit | 90836c3270786135dcae04c9eff80cdef9fe602c (patch) | |
| tree | 9983c22d53f85344e9cc406a991db1eb5e8e2b88 /sys/kern/kern_mutex.c | |
| parent | 2d78a5531ef1ac9bd45e67b7a04dee2f52e1f224 (diff) | |
Notes
Diffstat (limited to 'sys/kern/kern_mutex.c')
| -rw-r--r-- | sys/kern/kern_mutex.c | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index 35bbd5f78c3f..8e6133d6bfde 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -455,12 +455,11 @@ _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line) * sleep waiting for it), or if we need to recurse on it. */ void -__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts, +__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, const char *file, int line) { struct mtx *m; struct turnstile *ts; - uintptr_t v; #ifdef ADAPTIVE_MUTEXES volatile struct thread *owner; #endif @@ -489,7 +488,6 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts, lock_delay_arg_init(&lda, NULL); #endif m = mtxlock2mtx(c); - v = MTX_READ_VALUE(m); if (__predict_false(lv_mtx_owner(v) == (struct thread *)tid)) { KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0 || @@ -520,9 +518,8 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts, for (;;) { if (v == MTX_UNOWNED) { - if (_mtx_obtain_lock(m, tid)) + if (_mtx_obtain_lock_fetch(m, &v, tid)) break; - v = MTX_READ_VALUE(m); continue; } #ifdef KDTRACE_HOOKS @@ -674,12 +671,11 @@ _mtx_lock_spin_failed(struct mtx *m) * is handled inline. */ void -_mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts, - const char *file, int line) +_mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, + int opts, const char *file, int line) { struct mtx *m; struct lock_delay_arg lda; - uintptr_t v; #ifdef LOCK_PROFILING int contested = 0; uint64_t waittime = 0; @@ -706,12 +702,10 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts, #ifdef KDTRACE_HOOKS spin_time -= lockstat_nsecs(&m->lock_object); #endif - v = MTX_READ_VALUE(m); for (;;) { if (v == MTX_UNOWNED) { - if (_mtx_obtain_lock(m, tid)) + if (_mtx_obtain_lock_fetch(m, &v, tid)) break; - v = MTX_READ_VALUE(m); continue; } /* Give interrupts a chance while we spin. */ @@ -796,14 +790,11 @@ retry: m->lock_object.lo_name, file, line)); WITNESS_CHECKORDER(&m->lock_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL); - v = MTX_READ_VALUE(m); for (;;) { - if (v == MTX_UNOWNED) { - if (_mtx_obtain_lock(m, tid)) - break; - v = MTX_READ_VALUE(m); + if (_mtx_obtain_lock_fetch(m, &v, tid)) + break; + if (v == MTX_UNOWNED) continue; - } if (v == tid) { m->mtx_recurse++; break; @@ -896,11 +887,18 @@ __mtx_unlock_sleep(volatile uintptr_t *c, int opts, const char *file, int line) { struct mtx *m; struct turnstile *ts; + uintptr_t v; if (SCHEDULER_STOPPED()) return; m = mtxlock2mtx(c); + v = MTX_READ_VALUE(m); + + if (v == (uintptr_t)curthread) { + if (_mtx_release_lock(m, (uintptr_t)curthread)) + return; + } if (mtx_recursed(m)) { if (--(m->mtx_recurse) == 0) |
