summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_lock.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-09-29 18:02:23 +0000
committerkib <kib@FreeBSD.org>2013-09-29 18:02:23 +0000
commit632f1d29f39402167db9069d25e9bdc974b29c88 (patch)
treee521a2a30027732330389023ab5d36a15df225fc /sys/kern/kern_lock.c
parentf093c579801a670d1ae7a75f29919c66b2adae40 (diff)
downloadFreeBSD-src-632f1d29f39402167db9069d25e9bdc974b29c88.zip
FreeBSD-src-632f1d29f39402167db9069d25e9bdc974b29c88.tar.gz
Add LK_TRYUPGRADE operation for lockmgr(9), which attempts to
atomically upgrade shared lock to exclusive. On failure, error is returned and lock is not dropped in the process. Tested by: pho (previous version) No objections from: attilio Sponsored by: The FreeBSD Foundation MFC after: 1 week Approved by: re (glebius)
Diffstat (limited to 'sys/kern/kern_lock.c')
-rw-r--r--sys/kern/kern_lock.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index 74a5b19..8ca8acd 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -497,6 +497,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
op = LK_EXCLUSIVE;
break;
case LK_UPGRADE:
+ case LK_TRYUPGRADE:
case LK_DOWNGRADE:
_lockmgr_assert(lk, KA_XLOCKED | KA_NOTRECURSED,
file, line);
@@ -694,6 +695,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
}
break;
case LK_UPGRADE:
+ case LK_TRYUPGRADE:
_lockmgr_assert(lk, KA_SLOCKED, file, line);
v = lk->lk_lock;
x = v & LK_ALL_WAITERS;
@@ -714,6 +716,17 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
}
/*
+ * In LK_TRYUPGRADE mode, do not drop the lock,
+ * returning EBUSY instead.
+ */
+ if (op == LK_TRYUPGRADE) {
+ LOCK_LOG2(lk, "%s: %p failed the nowait upgrade",
+ __func__, lk);
+ error = EBUSY;
+ break;
+ }
+
+ /*
* We have been unable to succeed in upgrading, so just
* give up the shared lock.
*/
OpenPOWER on IntegriCloud