FreeBSD ZFS
The Zettabyte File System
Data Structures | Typedefs | Functions | Variables

rrwlock.c File Reference

A re-entrant read reader/writer lock (aka "rrwlock"). More...

#include <sys/refcount.h>
#include <sys/rrwlock.h>
Include dependency graph for rrwlock.c:

Go to the source code of this file.

Data Structures

struct  rrw_node

Typedefs

typedef struct rrw_node rrw_node_t

Functions

static rrw_node_trrn_find (rrwlock_t *rrl)
static void rrn_add (rrwlock_t *rrl)
 Add a node to the head of the singly linked list.
static boolean_t rrn_find_and_remove (rrwlock_t *rrl)
 If a node is found for 'rrl', then remove the node from this thread's list and return TRUE; otherwise return FALSE.
void rrw_init (rrwlock_t *rrl)
void rrw_destroy (rrwlock_t *rrl)
static void rrw_enter_read (rrwlock_t *rrl, void *tag)
static void rrw_enter_write (rrwlock_t *rrl)
void rrw_enter (rrwlock_t *rrl, krw_t rw, void *tag)
void rrw_exit (rrwlock_t *rrl, void *tag)
boolean_t rrw_held (rrwlock_t *rrl, krw_t rw)

Variables

uint_t rrw_tsd_key
 global key for TSD

Detailed Description

A re-entrant read reader/writer lock (aka "rrwlock").

This is a normal reader/writer lock with the additional feature of allowing threads who have already obtained a read lock to re-enter another read lock (re-entrant read) - even if there are waiting writers.

Callers who have not obtained a read lock give waiting writers priority.

The rrwlock_t lock does not allow re-entrant writers, nor does it allow a re-entrant mix of reads and writes (that is, it does not allow a caller who has already obtained a read lock to be able to then grab a write lock without first dropping all read locks, and vice versa).

The rrwlock_t uses tsd (thread specific data) to keep a list of nodes (rrw_node_t), where each node keeps track of which specific lock (rrw_node_t::rn_rrl) the thread has grabbed. Since re-entering should be rare, a thread that grabs multiple reads on the same rrwlock_t will store multiple rrw_node_ts of the same 'rrn_rrl'. Nodes on the tsd list can represent a different rrwlock_t. This allows a thread to enter multiple and unique rrwlock_ts for read locks at the same time.

Since using tsd exposes some overhead, the rrwlock_t only needs to keep tsd data when writers are waiting. If no writers are waiting, then a reader just bumps the anonymous read count (rr_anon_rcount) - no tsd is needed. Once a writer attempts to grab the lock, readers then keep tsd data and bump the linked readers count (rr_linked_rcount).

If there are waiting writers and there are anonymous readers, then a reader doesn't know if it is a re-entrant lock. But since it may be one, we allow the read to proceed (otherwise it could deadlock). Since once waiting writers are active, readers no longer bump the anonymous count, the anonymous readers will eventually flush themselves out. At this point, readers will be able to tell if they are a re-entrant lock (have a rrw_node_t entry for the lock) or not. If they are a re-entrant lock, then we must let the proceed. If they are not, then the reader blocks for the waiting writers. Hence, we do not starve writers.

Definition in file rrwlock.c.


Typedef Documentation

typedef struct rrw_node rrw_node_t

Function Documentation

static void rrn_add ( rrwlock_t rrl) [static]

Add a node to the head of the singly linked list.

Definition at line 98 of file rrwlock.c.

static rrw_node_t* rrn_find ( rrwlock_t rrl) [static]

Definition at line 80 of file rrwlock.c.

static boolean_t rrn_find_and_remove ( rrwlock_t rrl) [static]

If a node is found for 'rrl', then remove the node from this thread's list and return TRUE; otherwise return FALSE.

Definition at line 113 of file rrwlock.c.

void rrw_destroy ( rrwlock_t rrl)

Definition at line 147 of file rrwlock.c.

void rrw_enter ( rrwlock_t rrl,
krw_t  rw,
void *  tag 
)
Parameters:
[in]tagUsed in reference count tracking. The value used in rrw_enter() must also be used any corresponding rrw_exit()s.

Definition at line 210 of file rrwlock.c.

static void rrw_enter_read ( rrwlock_t rrl,
void *  tag 
) [static]

Definition at line 157 of file rrwlock.c.

static void rrw_enter_write ( rrwlock_t rrl) [static]

Definition at line 188 of file rrwlock.c.

void rrw_exit ( rrwlock_t rrl,
void *  tag 
)
Parameters:
[in]tagUsed in reference count tracking. The value used in rrw_exit() must match that used by its corresponding rrw_enter().

Definition at line 224 of file rrwlock.c.

boolean_t rrw_held ( rrwlock_t rrl,
krw_t  rw 
)

Definition at line 260 of file rrwlock.c.

void rrw_init ( rrwlock_t rrl)

Definition at line 136 of file rrwlock.c.


Variable Documentation

uint_t rrw_tsd_key

global key for TSD

Definition at line 72 of file rrwlock.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines