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)
This commit is contained in:
Konstantin Belousov 2013-09-29 18:02:23 +00:00
parent ca49624410
commit 7c6fe80353
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=255940
2 changed files with 14 additions and 0 deletions

View file

@ -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;
@ -713,6 +715,17 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
break;
}
/*
* 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.

View file

@ -169,6 +169,7 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
#define LK_RELEASE 0x100000
#define LK_SHARED 0x200000
#define LK_UPGRADE 0x400000
#define LK_TRYUPGRADE 0x800000
#define LK_TOTAL_MASK (LK_INIT_MASK | LK_EATTR_MASK | LK_TYPE_MASK)