Next Previous Contents

## 9. The Lock Package

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.

## 9.1 Key Design Choices

- The package must be simple and @u[fast]: in the case that a lock can be
- obtained immediately, it should require a minimum of instructions;
- All the processes using a lock are trustworthy;
- The lock routines ignore priorities;

### A Simple Example

@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)

## 9.2 Lock Primitives

### Lock_Init -- Initialize a lock

### Call:

void Lock_Init( @w<out struct Lock *lock> )

### Parameters:

lock

  The (address of the) lock to be initialized,

### Completion Codes:

N/A

### Description:

This routine must be called to initialize a lock before it is used.

### ObtainReadLock -- Obtain a read lock

### Call:

ObtainReadLock( @w<in out struct Lock *lock> )

### Parameters:

lock

  The lock to be read-locked,

### Completion Codes:

N/A

### Description:

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 -- Obtain a write lock

### Call:

ObtainWriteLock( @w<in out struct Lock *lock> )

### Parameters:

lock

  The lock to be write-locked

### Completion Codes:

N/A

### Description:

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 -- Release a read lock

### Call:

ReleaseReadLock( @w<in out struct Lock *lock> )

### Parameters:

lock

  The lock to be released

### Completion Codes:

N/A

### Description:

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 -- Release a write lock

### Call:

ReleaseWriteLock( @w<in out struct Lock *lock> )

### Parameters:

lock

  The lock to be released

### Completion Codes:

N/A

### Description:

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 -- Check the status of a lock

### Call:

CheckLock( @w<in struct Lock *lock> )

### Parameters:

lock

  The lock to be checked

### Completion Codes:

N/A

### Description:

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. )

Next Previous Contents