Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site ucbvax.BERKELEY.EDU Path: utzoo!decvax!ucbvax!CSNET-RELAY.ARPA!DCATHEY%1175%ti-eg.CSNET From: DCATHEY%1175%ti-eg.CSNET@CSNET-RELAY.ARPA ("David L. Cathey, DEIS/DCS VA Newsgroups: mod.computers.vax Subject: RE: Critical Regions in VAX/VMS Message-ID: <8608161855.AA09178@ucbvax.Berkeley.EDU> Date: Sat, 16-Aug-86 14:56:13 EDT Article-I.D.: ucbvax.8608161855.AA09178 Posted: Sat Aug 16 14:56:13 1986 Date-Received: Sat, 16-Aug-86 23:27:44 EDT Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet Lines: 77 Approved: info-vax@sri-kl.arpa >The original requestor asked how to increment a shared variable at some point >in a program, but be able to have an exit handler know whether or not the >increment instruction was performed yet. ... > ... Someone suggested using VMS Locks, which are used >to synchronize critical regions of several processes. The poster forgot to >mention that the lock would have to be applied between multiple threads of >a single process in this application, as in > > clear go_to_exit_handler > lock the counter > increment the counter > unlock the counter > if go_to_exit_handler then goto exit handler > >and in the exception handler > > test the counter lock > if locked, then dismiss the exception and continue (don't know > whether increment is done or not) after setting > go_to_exit_handler (so that we regain control later) > go to exit handler > > exit handler > if counter has been incremented then decrement it > You missed my point. Use the lock itself as the counter. The $GETLKI system service will tell you the number of locks against the resource, which is the value of your "counter". The method you show of using the locks still may not work correctly if the process is deleted. If the lock itself is the counter, when all user-mode locks are $DEQueued, the counter is automatically "decremented" without needing exception/exit handlers. I.E.: increment(){ SYS$ENQW(...) ; } decrement(){ SYS$DEQ(...) ; } value_of_counter(){ SYS$GETLKI(... using the LKI$_LCKCOUNT item code ...) return(...LKI$_LCKCOUNT result ...) ; } By the original poster's phrasing of his application, you don't even need to have an exlusive lock. He just wants to make sure that if he increments the variable, he decrements the variable. The lock services are more useful in process communication than just restricting access to resources. >A much more efficient way to create an atomic increment-and-remember-that-I-did >operation is to use IPL synchronization. In the main program, replace the >increment with > > status = call sys$cmkrnl( increment_and_remember, %REF(counter), > %REF(flag) ) > > status = call sys$cmkrnl( decrement_and_forget, %REF(counter...)) > > increment_and_remember: > save IPL > elevate to IPL$_ASTDEL > increment counter > set flag > restore IPL > True, but they seemed to want to avoid privileged code. And KERNEL code is very privileged. Since he is raising IPL to ASTDEL or greater, they would also have to lock key pages in memory to prevent page faults (Locking pages in working set might do, but the process would have to disable process swap mode...). 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...]