diff options
author | kib <kib@FreeBSD.org> | 2013-09-29 18:02:23 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-09-29 18:02:23 +0000 |
commit | 632f1d29f39402167db9069d25e9bdc974b29c88 (patch) | |
tree | e521a2a30027732330389023ab5d36a15df225fc /sys/kern | |
parent | f093c579801a670d1ae7a75f29919c66b2adae40 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/kern/kern_lock.c | 13 |
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. */ |