Operating System - OpenVMS

Locking Mechanism in VMS

Not applicable

Locking Mechanism in VMS


I am learning locking mechanism in VMS and I have one query regarding this.

Suppose there is one resource by name XYZ.

Process A has taken a lock on XYZ in NL mode.
Process B has taken a lock on XYZ in PR mode.
Process c has queued the lock on XYZ in EX mode as:
sys$enqw( 0, LCK$K_EXMODE, &lockStatusBlock, (LCK$M_SYSTEM | LCK$M_VALBLK),
"XYZ", 0, 0, 0, 0,0, 0, 0);

After this,
Process A tries to convert the lock from NL to PR mode as:

sys$enqw( 0, LCK$K_PRMODE, &lockStatusBlock, (LCK$M_SYSTEM | LCK$M_CONVERT | LCK$M_VALBLK), "XYZ", 0, 0,0,0, 0, 0);

I want to know whether Process A will be able to convert it from NL to PR mode or not.

I think Process A will convert the lock from NL to PR since PR is compatible with PR.

But I want, Process C request to be completed first, as Process C has queued the lock request prior to lock conversion request from Process A.

Can anyone guide me, how can I achieve that.

Can it be achived by using LCK$M_QUECVT flag.

Hein van den Heuvel
Honored Contributor

Re: Locking Mechanism in VMS


The potential problem you describe is often referred to as 'write lock starvation'.

The default operation for the Lock manager is to grant a compatible convert. But this may cause an incompatible convert to never happen. It will starve on the queue.

I believe QUECVT is precisely there to prevent/control this, but I haven't though about these things for a while adn the documentation is rather terse on the matter. It would have been nice if the chapter 7 in the 'programming concepts' manual addressed this:

Hey, why not just try with a few debug sessions?
You would want to know for sure how your program react in this condisiton.

Teh system service reference manual only says:

" LCK$M_QUECVT This flag is valid only for conversion operations. A conversion request with the LCK$M_QUECVT flag set will be forced to wait behind any already queued conversions.

The conversion request is granted immediately, if there are no already queued conversions."

But you certainly read that already

Hope this help some,

Not applicable

Re: Locking Mechanism in VMS

Hi Hein,

Thanks for your help.

You are right "The default operation for the Lock manager is to grant a compatible convert. But this may cause an incompatible convert to never happen. It will starve on the queue."

But is there a way to avoid it.

I simply want that Process A should convert the lock in PR mode only after Process C has got the lock on EX mode and not before that.

Is there any other way to achive it.

David Jones_21
Trusted Contributor

Re: Locking Mechanism in VMS

I believe in your case, process C is blocking on the waiting queue and not the conversion queue, so LCK$M_QUECVT won't do what you want. If you change the sequence so process C starts with a NL mode lock that it then converts to EX mode, then I think the QUECVT modifier on process A's convert will wait until process C completes and lowers its lock to a compatible mode.
I'm looking for marbles all day long.
Jon Pinkley
Honored Contributor

Re: Locking Mechanism in VMS

David is correct, LCK$M_QUECVT won't cause process A to wait for process C to obtain and release the resource, unless process C is waiting in the conversion queue instead of the waiting queue.

One clarification to what David suggested. When process C requests the NL lock, it should specify the LCK$M_EXPEDITE flag, to guarantee that the $ENQ of the new lock will not be blocked.

New locks are treated differently than lock conversions, and they will block if there are any locks in either the conversion or the waiting queue. I.e. if there is a lock granted at PR, a lock waiting at EX, and a new lock is queued for NL, it will be placed in the waiting queue behind the EX lock. The expedite flag can avoid the wait queue for the special case of a new NL request.

See "HP OpenVMS Programming
Concepts Manual, Volume I" http://h71000.www7.hp.com/doc/82FINAL/5841/aa-rnshd-te.PDF Chapter 7, "Synchronizing Access to Resources" for more details. Specifically, see "Figure 7-2 Three Lock Queues" for a graphic showing the lock queues that are maintained for each resource. As you can see, there is no path from the granted queue to the wait queue, and that is what would be needed to allow for the locking protocol you require if process C's new lock request is waiting in the wait queue.

Unfortunately, there is no LCK$M_QUEWAIT flag that would allow for the behavior of a new lock request, without the possibility of loosing the lock value block.

However, we can force all waiting to occur in the convert queue. The following is a locking protocol that should work the way you want.

When obtaining a new lock, always specify the mode as NL, and flag as EXPEDITE. This will always grant the lock immediately regardless of whether there are locks waiting in either the wait or convert queue.

When converting to a mode that could result in a wait, specify the QUECVT flag. This will cause the locks in the convert queue to be processed in FIFO (first in, first out) order.

Process C should $ENQ the new lock with NL mode and with the EXPEDITE flag. After the lock has been granted at NL, then convert the NL to EX, thus forcing any waiting will be done in the convert queue (QUECVT has no effect when converting to EX that I can think of, but it won't hurt).

Process A should convert from NL to PR and specify QUECVT, so the conversion to PR will not occur before process C's conversion to EX.

Good Luck,

it depends
Hein van den Heuvel
Honored Contributor

Re: Locking Mechanism in VMS

Yeah, that's pretty much how RMS neeed to do it when they changed from always bouncing NL -> EX into holding on to locks in PR mode (for global buffers only).
Initial ENQ to NL + Expidite.
When needed convert up.

From the reading of RMS, Chapter RM0CACHE,
versus 'comments' by Elinor in 2000:

"first get a NL (EXPEDITE) lock and then convert it to EX so that all EX requests will now go into conversion queue. This is to prevent possibility of lock starvation with implementation of new read-mode locks: new EX lock request (wait queue) starved out by NL->EX conversion requests (conversion queue)."

You still have to go careful with respect to dealock potential. RMS opted for a LCK$M_NOQUEUE in certain conditions.

Honored Contributor

Re: Locking Mechanism in VMS

>>> Can anyone guide me, how can I achieve that. <<<

Are you looking to learn the innards of locking and of the lock mode state transitions (and a state table is what you really want to and need to look at here), or do you have specific application requirement(s) or desired outcome(s)?

If it is the latter case, please consider avoiding asking specific questions -- that approach is infinitely inviting, and certainly gets you specific answers, though (in my experience) answer(s) that can be less suited or even ill-suited to your particular requirement; more general questions and background can provide you with other and potentially better approach(es) that might be available.

Put another way, what are you up to here?

And as a rule of thumb, I prefer to always start with an NL lock, and only release the lock when I'm really done and have no plans to reacquire the lock. I tend to prefer to down-convert to NL before releasing ($deq), too, as this avoids a nasty race condition that can creep in. Down-convert to NL followed by $deq is synchronous. $deq[w] alone can be asynchronous.

Stephen Hoffman
HoffmanLabs LLC
Claus Olesen

Re: Locking Mechanism in VMS

You asked also about another way. I thought blocking ast (did not know
It would run in the readers triggered by the writer. It would trigger the
readers to (finish up and) unlock (and perhaps relock right away depending on
your app) thereby creating an opportunity for the writer to lock. An additional
lock might be needed to keep readers off the lock until the writer has
locked. But I do not know if this is another or even worthwhile way.
Willem Grooters
Honored Contributor

Re: Locking Mechanism in VMS

A lock request will be granted if the level is compatible with the current level granted.
Waiting higher level locks are not taken into account.

In your case: The PR lock of proces A will be granted since there is a PR lock granted at this moment. The EX lock will be granted when both process A and B have no, or NL mode locks.

In a similar situation, I have done this:

processes A and B have PR lock on resource X, with AST to be fired when a higher level lock is requested. They also have NL lock on ressource Y.
Process C issues EX request to resource Y - which is granted since NL is compatible. Then it requests a EX lock on resource X, and will wait until it's granted.
By that reqest, the AST's in process A and B are fired. The locks on resource X are converted to NL - these will be granted. The locks on resource Y are converted to PR, but these are queued since process C has an EX lock here.
When both process A and B have NL locks on resource X, the EX lock of process C on rsource X is granted. The EX lock on resource Y is now released, causing the pending PR locks to be granted. Immediately, the processes A and B convert these locks back to NL, their NL locks on resource X to PR - and wait until process C has done it's job and releases resource X again.

Resources are just names. Locking on VMS is a 'gentlemen's agreement'. All 'users' of a resource should adhere to the locking scheme.

In the example, the scheme is simple: Either resource would only be accessed using NL, PR and EX mode locks.
Willem Grooters
OpenVMS Developer & System Manager
Jon Pinkley
Honored Contributor

Re: Locking Mechanism in VMS

RE:"A lock request will be granted if the level is compatible with the current level granted.
Waiting higher level locks are not taken into account."

The above is true if the QUECVT flag is not specified. However, if there is another lock waiting in the CONVERT queue (not the waiting queue), then the lock converted with the QUECVT flag will wait even if the requested mode is compatible with the granted mode.

I verified this behavior using Ken Coar's DCL LOCK command.

Jon Pinkley
it depends