xref: /onnv-gate/usr/src/uts/common/fs/zfs/sys/rrwlock.h (revision 5326:6752aa2bd5bc)
1*5326Sek110237 /*
2*5326Sek110237  * CDDL HEADER START
3*5326Sek110237  *
4*5326Sek110237  * The contents of this file are subject to the terms of the
5*5326Sek110237  * Common Development and Distribution License (the "License").
6*5326Sek110237  * You may not use this file except in compliance with the License.
7*5326Sek110237  *
8*5326Sek110237  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5326Sek110237  * or http://www.opensolaris.org/os/licensing.
10*5326Sek110237  * See the License for the specific language governing permissions
11*5326Sek110237  * and limitations under the License.
12*5326Sek110237  *
13*5326Sek110237  * When distributing Covered Code, include this CDDL HEADER in each
14*5326Sek110237  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5326Sek110237  * If applicable, add the following below this CDDL HEADER, with the
16*5326Sek110237  * fields enclosed by brackets "[]" replaced with your own identifying
17*5326Sek110237  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5326Sek110237  *
19*5326Sek110237  * CDDL HEADER END
20*5326Sek110237  */
21*5326Sek110237 /*
22*5326Sek110237  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*5326Sek110237  * Use is subject to license terms.
24*5326Sek110237  */
25*5326Sek110237 
26*5326Sek110237 #ifndef	_SYS_RR_RW_LOCK_H
27*5326Sek110237 #define	_SYS_RR_RW_LOCK_H
28*5326Sek110237 
29*5326Sek110237 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*5326Sek110237 
31*5326Sek110237 #ifdef	__cplusplus
32*5326Sek110237 extern "C" {
33*5326Sek110237 #endif
34*5326Sek110237 
35*5326Sek110237 #include <sys/inttypes.h>
36*5326Sek110237 #include <sys/zfs_context.h>
37*5326Sek110237 #include <sys/refcount.h>
38*5326Sek110237 
39*5326Sek110237 /*
40*5326Sek110237  * A reader-writer lock implementation that allows re-entrant reads, but
41*5326Sek110237  * still gives writers priority on "new" reads.
42*5326Sek110237  *
43*5326Sek110237  * See rrwlock.c for more details about the implementation.
44*5326Sek110237  *
45*5326Sek110237  * Fields of the rrwlock_t structure:
46*5326Sek110237  * - rr_lock: protects modification and reading of rrwlock_t fields
47*5326Sek110237  * - rr_cv: cv for waking up readers or waiting writers
48*5326Sek110237  * - rr_writer: thread id of the current writer
49*5326Sek110237  * - rr_anon_rount: number of active anonymous readers
50*5326Sek110237  * - rr_linked_rcount: total number of non-anonymous active readers
51*5326Sek110237  * - rr_writer_wanted: a writer wants the lock
52*5326Sek110237  */
53*5326Sek110237 typedef struct rrwlock {
54*5326Sek110237 	kmutex_t	rr_lock;
55*5326Sek110237 	kcondvar_t	rr_cv;
56*5326Sek110237 	kthread_t	*rr_writer;
57*5326Sek110237 	refcount_t	rr_anon_rcount;
58*5326Sek110237 	refcount_t	rr_linked_rcount;
59*5326Sek110237 	boolean_t	rr_writer_wanted;
60*5326Sek110237 } rrwlock_t;
61*5326Sek110237 
62*5326Sek110237 /*
63*5326Sek110237  * 'tag' is used in reference counting tracking.  The
64*5326Sek110237  * 'tag' must be the same in a rrw_enter() as in its
65*5326Sek110237  * corresponding rrw_exit().
66*5326Sek110237  */
67*5326Sek110237 void rrw_init(rrwlock_t *rrl);
68*5326Sek110237 void rrw_destroy(rrwlock_t *rrl);
69*5326Sek110237 void rrw_enter(rrwlock_t *rrl, krw_t rw, void *tag);
70*5326Sek110237 void rrw_exit(rrwlock_t *rrl, void *tag);
71*5326Sek110237 boolean_t rrw_held(rrwlock_t *rrl, krw_t rw);
72*5326Sek110237 
73*5326Sek110237 #define	RRW_READ_HELD(x)	rrw_held(x, RW_READER)
74*5326Sek110237 #define	RRW_WRITE_HELD(x)	rrw_held(x, RW_WRITER)
75*5326Sek110237 
76*5326Sek110237 #ifdef	__cplusplus
77*5326Sek110237 }
78*5326Sek110237 #endif
79*5326Sek110237 
80*5326Sek110237 #endif	/* _SYS_RR_RW_LOCK_H */
81