| 1263 | } |
| 1264 | |
| 1265 | int |
| 1266 | lockmgr_unlock(struct lock *lk) |
| 1267 | { |
| 1268 | uintptr_t x, tid; |
| 1269 | const char *file; |
| 1270 | int line; |
| 1271 | |
| 1272 | file = __FILE__; |
| 1273 | line = __LINE__; |
| 1274 | |
| 1275 | _lockmgr_assert(lk, KA_LOCKED, file, line); |
| 1276 | x = lockmgr_read_value(lk); |
| 1277 | if (__predict_true(x & LK_SHARE) != 0) { |
| 1278 | lockmgr_note_shared_release(lk, file, line); |
| 1279 | if (lockmgr_sunlock_try(lk, &x)) { |
| 1280 | LOCKSTAT_PROFILE_RELEASE_RWLOCK(lockmgr__release, lk, LOCKSTAT_READER); |
| 1281 | } else { |
| 1282 | return (lockmgr_sunlock_hard(lk, x, LK_RELEASE, NULL, file, line)); |
| 1283 | } |
| 1284 | } else { |
| 1285 | tid = (uintptr_t)curthread; |
| 1286 | lockmgr_note_exclusive_release(lk, file, line); |
| 1287 | if (x == tid && atomic_cmpset_rel_ptr(&lk->lk_lock, tid, LK_UNLOCKED)) { |
| 1288 | LOCKSTAT_PROFILE_RELEASE_RWLOCK(lockmgr__release, lk,LOCKSTAT_WRITER); |
| 1289 | } else { |
| 1290 | return (lockmgr_xunlock_hard(lk, x, LK_RELEASE, NULL, file, line)); |
| 1291 | } |
| 1292 | } |
| 1293 | return (0); |
| 1294 | } |
| 1295 | |
| 1296 | int |
| 1297 | __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, |
no test coverage detected