Specifications
System Macros Invoked by Drivers
FORKLOCK
In a multiprocessing environment, the FORKLOCK macro stores the fork lock
index in R0 and calls SMP$ACQUIRE. SMP$ACQUIRE uses the value in R0
to locate the fork lock structure in the system spinlock database (a pointer
to which is located at SMP$AR_SPNLKVEC). Prior to securing the fork lock,
SMP$ACQUIRE raises IPL to its associated IPL (SPL$B_IPL).
In both processing environments, the FORKLOCK macro performs the following
tasks:
• Preserves R0 through the macro call (if preserve=YES is specified)
• Preserves the current IPL at the specified location (if savipl is specified)
• Sets the SMP-modified bit in the driver prologue table (DPT$V_SMPMOD in
DPT$L_FLAGS)
Example
FORKLOCK -
LOCK=UCB$B_FLCK(R5),- ;Lock fork database
SAVIPL=-(SP),- ;Save the current IPL
PRESERVE=NO ;Do not preserve R0
INCW UCB$W_QLEN(R5) ;Bump device queue length
BBSS #UCB$V_BSY,UCB$W_STS(R5),-
20$ ;If set, device is busy
PUSHL R5 ;Save UCB address
BSBW IOC$INITIATE ;Initiate I/O function
POPL R5 ;Restore UCB address
FORKUNLOCK -
LOCK=UCB$B_FLCK(R5),- ;Unlock fork database
NEWIPL=(SP)+,- ;Restore previous IPL
PRESERVE=NO ;Do not preserve R0
RSB
.
.
.
20$: ;Place IRP in UCB pending-I/O queue
The system routine that determines whether a device can immediately service
an I/O request synchronizes its access to the fork database by invoking the
FORKLOCK macro. The FORKLOCK macro raises IPL to fork IPL and, in a
multiprocessing environment, obtains the corresponding fork lock.
Thus synchronized, the system routine tests a bit in the UCB to determine
whether the device is busy. If the device is not busy, the operating system calls
a routine that initiates driver processing of the I/O request, still at fork IPL
and holding the fork lock. Later, possibly with an invocation of the WFIKPCH
macro, the driver start-I/O routine returns control to this routine, which issues
the FORKUNLOCK macro to relinquish fork level synchronization.
2–35