[mod.computers.vax] Is it possible to do critical regions in VMS?

libes@nbs-amrf.UUCP (08/06/86)

Is it possible to do critical regions in VMS?  I would prefer
non-privileged code but, if necessary, some weird privs would be
acceptable.

My problem is as follows:

int x = 0;
main() {
	while (1) {
		increment();
		decrement();
	}
}

increment() {x++;}
decrement() {x--;}

The user can call subroutines increment and decrement in strictly
alternating sequence (as is done here in main()).  However, he may
^c or exit (via forcex() or the debugger) at any time.  I would
like to ensure that x is 0.

The reason I can't just set it to 0, is that x is actually shared
with several other processes (all doing the same thing).

I'm at a loss on how to do this.  I'm already using an exit
handler, but the exit handler can't tell if it needs to decrement x
or not (x actually takes on values > 1, so it can't tell if we've
incremented x a different number of times than we've decremented
it).

No matter how I write it, there is always a window in which
I will have a problem.  If I could do critical regions in VMS I
would like to do something like this:

	increment() {
		enter_critical_region(); /* block ^c, ^y, forcex(), etc */
		x++;
		incremented = TRUE;
		exit_critical_region();  /* ok, now I'm willing to exit */
	}

	exit_handler() {
		if (incremented) x--;
	}

(In case it's important, I'm using Fortran (patching someone else's
code).  I'm assuming a language-independent VMS-dependent solution.)
I would appreciate it if anyone has a solution to this seemingly
simple problem.  Thanks.

(If anyone knows how to do critical regions in general in VMS, I
would like to know, as all the people around here that I asked said
that they had run into this problem before to no avail.)

Don Libes       {seismo,umcp-cs}!nbs-amrf!libes		(301) 921-2171

DCATHEY%MCCORE%ti-eg.CSNET@CSNET-RELAY.ARPA ("David L. Cathey, DEIS/DCS) (08/08/86)

            
	Yes, it is possible to do critical regions in VMS.  However,
the more critical it is, the more privileged you need to be.  Since
you are wanting a critical region to guard against any action that
the operating system might take against you, very privileged code is
required (like Kernel mode at elevated IPL...).

	However by looking at your example, there may be a more elegant
solution.  Does the counter need to be in any particular form?  How about
ENQueueing a lock (probably a NULL lock) for the "increment" function and
DEQueueing a lock for the "decrement" function.

	This will provide a mechanism to "increment" a variable that when
the process goes away, or the image is run down, will automatically be
"decremented".  The $GETLKI system service (by specifing LKI$_LCKCOUNT
(lock count) in the item list) will be able to tell you the "value" of the
variable.  If this variable is global across the entire system, you will need
the SYSLCK privilege.  If all the process are in the same job group, it
will require no privileges.

	This does not really answer the question about critical regions,
but allows the operating system to work for you so that the critical region
isn't needed.  If this doesn't help, then I think you will have to look
at User-written System Services in order to control the incrementing and
decrementing of a variable.  The run-down vector in the USS can be used
to decrement if needed so that you stay properly synchronized.


						David L. Cathey
						VAX System Support
						Texas Instruments Incorporated

[Not only are these views not those of my employer, I had to tie him up
	so I could type this in...]