A mutual-exclusion lock, or mutex, is usually associated with a set of data and regulates access to that data. Mutexes provide a way to allow only one thread at a time access to that data. The mutex functions are:
Releases any associated storage.
Acquires a mutex.
Releases a mutex.
Initializes a mutex.
Tests to determine whether the mutex is held by the current thread. To be used in ASSERT(9F) only.
Acquires a mutex if available, but does not block.
Device drivers usually allocate a mutex for each driver data structure. The mutex is typically a field in the structure of type kmutex_t. mutex_init(9F) is called to prepare the mutex for use. This call is usually made at attach(9E) time for per-device mutexes and _init(9E) time for global driver mutexes.
For example,
struct xxstate *xsp; /* ... */ mutex_init(&xsp->mu, NULL, MUTEX_DRIVER, NULL); /* ... */
For a more complete example of mutex initialization, see Chapter 6, Driver Autoconfiguration.
The driver must destroy the mutex with mutex_destroy(9F) before being unloaded. Destroying the mutex is usually done at detach(9E) time for per-device mutexes and _fini(9E) time for global driver mutexes.
Every section of the driver code that needs to read or write the shared data structure must do the following tasks:
Acquire the mutex
Access the data
Release the mutex
The scope of a mutex, that is, the data the mutex protects, is entirely up to the programmer. A mutex protects a data structure only if every code path that accesses the data structure does so while holding the mutex.