The lock package contains a number of routines and macros that allow C programs that utilize the LWP abstraction to place read and write locks on data structures shared by several light-weight processes. Like the LWP package, the lock package was written with simplicity in mind -- there is no protection inherent in the model.
In order to use the locking mechanism for an object, an object
of type
struct Lock
must be associated with the
object. After being initialized, with a call to @Lock(Init), the
lock is used in invocations of the macros ObtainReadLock,
ObtainWriteLock, ReleaseReadLock and ReleaseWriteLock.
The semantics of a lock is such that any number of readers may hold a lock. But only a single writer (and no readers) may hold the clock at any time. The lock package guarantees fairness: each reader and writer will eventually have a chance to obtain a given lock. However, this fairness is only guaranteed if the priorities of the competing processes are identical. Note that no ordering is guaranteed by the package.
In addition, it is illegal for a process to request a particular lock more than once, without first releasing it. Failure to obey this restriction may cause deadlock.
@Begin(program) #include "lock.h"
struct Vnode { . . . struct Lock lock; /* Used to lock this vnode */ . . . };
#define READ 0 #define WRITE 1
struct Vnode *get_vnode (name, how) char *name; int how; { struct Vnode *v;
v = lookup (name); if (how == READ) ObtainReadLock ( & v- > lock); else ObtainWriteLock ( & v- > lock); } @End(program)
void Lock_Init( @w < out struct Lock *lock > )
The (address of the) lock to be initialized,
N/A
This routine must be called to initialize a lock before it is used.
ObtainReadLock( @w < in out struct Lock *lock > )
The lock to be read-locked,
N/A
A read lock will be obtained on the specified lock. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression.
ObtainWriteLock( @w < in out struct Lock *lock > )
The lock to be write-locked
N/A
A write lock will be obtained on the specified lock. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression. )
ReleaseReadLock( @w < in out struct Lock *lock > )
The lock to be released
N/A
The specified lock will be released. This macro requires that the lock must have been previously read-locked. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression.
ReleaseWriteLock( @w < in out struct Lock *lock > )
The lock to be released
N/A
The specified lock will be released. This macro requires that the lock must have been previously write-locked. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression. )
CheckLock( @w < in struct Lock *lock > )
The lock to be checked
N/A
This macro yields an integer that specifies the status of the indicated lock. The value will be -1 if the lock is write-locked 0 if unlocked, or a positive integer that indicates the numer of readers with read locks. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression. )