Resource Locking A common problem in real-time systems is serializing access to a shared resource. One typical example is a global common data area that is read and written by several programs. Only one program at a time can safely write to the common area. RSX lacks any resource locking directives. However a resource lock is easily implemented using a global or group event flag and the event flag directives. The lock is considered set when the flag is cleared and free when the flag is set. The following code sequence shows how to properly use the directives: EV.LCK = 32. ;Lock event flag 1000$: CLEF$S #EV.LCK ;Test for the lock CMP #IS.SET,$DSW ;Was lock previous set BEQ 2000$ ; If EQ - yes, granted WTSE$S #EV.LCK ;Wait for the lock BR 1000$ ;Loop and try again 2000$: . . . ;Process with lock set SETF$S #EV.LCK ;Release the lock DECL$S ;Declare event The CLEF$S directive returns status IS.SET if the flag was previously set (lock available). If not, the program simply waits for the current holder to set the event flag and attempts to get the lock again. At system startup, the global lock flag must be initially turned on. The DECL$S is optional and only used if you consider releasing a lock to be an event that should cause task rescheduling (also applies to subsequent examples). The above algorithm works well, but would be expensive in terms of CPU time if a program was locking and unlocking a resource very often (more than once a second). A resource lock can also be coded by using a word in global common. The initial word value is set to one. The lock is granted when the word can be decremented to zero and denied for any other result. In the following example, LCKFLG is a variable defined in a global common. 1000$: DEC LCKFLG ;Test for the lock BEQ 2000$ ; If EQ - yes, granted INC LCKFLG ;Reset the attempt WSIG$S ;Wait for some event BR 1000$ ; and loop 2000$: . . . ;Process with lock set INC LCKFLG ;Release the lock This algorithm only takes a few instructions to set and release the lock. Its one flaw is that a task may keep waking up from the WSIG$S directive when the lock is known to not be free. The two algorithms can be combined. The global common word is used for the first lock access. Any subsequent lock attempts will wait on the global event flag. Note, this algorithm assumes the global event flag is initially clear. EV.LCK = 32. ;Lock event flag 1000$: DEC LCKFLG ;Test for the lock BEQ 2000$ ; If EQ - yes, granted 1100$: WTSE$S #EV.LCK ;Wait for the lock CLEF$S #EV.LCK ;Test for the lock CMP #IS.SET,$DSW ;Was lock previous set BNE 1100$ ; If NE - no, loop 2000$: . . . ;Process with lock set INC LCKFLG ;Release the lock BGT 3000$ ; If GT - last release SETF$S #EV.LCK ;Release the lock 3000$: For the majority of cases when a single program sets, processes and releases the lock, only four instructions are executed. Any subsequent attempt to gain the lock will wait quietly until the lock is available. All three algorithms work equally well and have the same flaw. If the task holding the lock exits or aborts, the lock will remain set. This is one advantage a RSX resource locking directive would have over these techniques.