xref: /titanic_41/usr/src/uts/common/fs/zfs/sys/rrwlock.h (revision 8f72ee6d994ea9ab828d444a1aa43fdedfeedc2a)
1f18faf3fSek110237 /*
2f18faf3fSek110237  * CDDL HEADER START
3f18faf3fSek110237  *
4f18faf3fSek110237  * The contents of this file are subject to the terms of the
5f18faf3fSek110237  * Common Development and Distribution License (the "License").
6f18faf3fSek110237  * You may not use this file except in compliance with the License.
7f18faf3fSek110237  *
8f18faf3fSek110237  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f18faf3fSek110237  * or http://www.opensolaris.org/os/licensing.
10f18faf3fSek110237  * See the License for the specific language governing permissions
11f18faf3fSek110237  * and limitations under the License.
12f18faf3fSek110237  *
13f18faf3fSek110237  * When distributing Covered Code, include this CDDL HEADER in each
14f18faf3fSek110237  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f18faf3fSek110237  * If applicable, add the following below this CDDL HEADER, with the
16f18faf3fSek110237  * fields enclosed by brackets "[]" replaced with your own identifying
17f18faf3fSek110237  * information: Portions Copyright [yyyy] [name of copyright owner]
18f18faf3fSek110237  *
19f18faf3fSek110237  * CDDL HEADER END
20f18faf3fSek110237  */
21f18faf3fSek110237 /*
22f18faf3fSek110237  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23f18faf3fSek110237  * Use is subject to license terms.
24f18faf3fSek110237  */
254445fffbSMatthew Ahrens /*
264445fffbSMatthew Ahrens  * Copyright (c) 2012 by Delphix. All rights reserved.
274445fffbSMatthew Ahrens  */
28f18faf3fSek110237 
29f18faf3fSek110237 #ifndef	_SYS_RR_RW_LOCK_H
30f18faf3fSek110237 #define	_SYS_RR_RW_LOCK_H
31f18faf3fSek110237 
32f18faf3fSek110237 #ifdef	__cplusplus
33f18faf3fSek110237 extern "C" {
34f18faf3fSek110237 #endif
35f18faf3fSek110237 
36f18faf3fSek110237 #include <sys/inttypes.h>
37f18faf3fSek110237 #include <sys/zfs_context.h>
38f18faf3fSek110237 #include <sys/refcount.h>
39f18faf3fSek110237 
40f18faf3fSek110237 /*
41f18faf3fSek110237  * A reader-writer lock implementation that allows re-entrant reads, but
42f18faf3fSek110237  * still gives writers priority on "new" reads.
43f18faf3fSek110237  *
44f18faf3fSek110237  * See rrwlock.c for more details about the implementation.
45f18faf3fSek110237  *
46f18faf3fSek110237  * Fields of the rrwlock_t structure:
47f18faf3fSek110237  * - rr_lock: protects modification and reading of rrwlock_t fields
48f18faf3fSek110237  * - rr_cv: cv for waking up readers or waiting writers
49f18faf3fSek110237  * - rr_writer: thread id of the current writer
50f18faf3fSek110237  * - rr_anon_rount: number of active anonymous readers
51f18faf3fSek110237  * - rr_linked_rcount: total number of non-anonymous active readers
52f18faf3fSek110237  * - rr_writer_wanted: a writer wants the lock
53f18faf3fSek110237  */
54f18faf3fSek110237 typedef struct rrwlock {
55f18faf3fSek110237 	kmutex_t	rr_lock;
56f18faf3fSek110237 	kcondvar_t	rr_cv;
57f18faf3fSek110237 	kthread_t	*rr_writer;
58f18faf3fSek110237 	refcount_t	rr_anon_rcount;
59f18faf3fSek110237 	refcount_t	rr_linked_rcount;
60f18faf3fSek110237 	boolean_t	rr_writer_wanted;
613b2aab18SMatthew Ahrens 	boolean_t	rr_track_all;
62f18faf3fSek110237 } rrwlock_t;
63f18faf3fSek110237 
64f18faf3fSek110237 /*
65f18faf3fSek110237  * 'tag' is used in reference counting tracking.  The
66f18faf3fSek110237  * 'tag' must be the same in a rrw_enter() as in its
67f18faf3fSek110237  * corresponding rrw_exit().
68f18faf3fSek110237  */
693b2aab18SMatthew Ahrens void rrw_init(rrwlock_t *rrl, boolean_t track_all);
70f18faf3fSek110237 void rrw_destroy(rrwlock_t *rrl);
71f18faf3fSek110237 void rrw_enter(rrwlock_t *rrl, krw_t rw, void *tag);
723b2aab18SMatthew Ahrens void rrw_enter_read(rrwlock_t *rrl, void *tag);
73*8f72ee6dSArne Jansen void rrw_enter_read_prio(rrwlock_t *rrl, void *tag);
743b2aab18SMatthew Ahrens void rrw_enter_write(rrwlock_t *rrl);
75f18faf3fSek110237 void rrw_exit(rrwlock_t *rrl, void *tag);
76f18faf3fSek110237 boolean_t rrw_held(rrwlock_t *rrl, krw_t rw);
774445fffbSMatthew Ahrens void rrw_tsd_destroy(void *arg);
78f18faf3fSek110237 
79f18faf3fSek110237 #define	RRW_READ_HELD(x)	rrw_held(x, RW_READER)
80f18faf3fSek110237 #define	RRW_WRITE_HELD(x)	rrw_held(x, RW_WRITER)
813b2aab18SMatthew Ahrens #define	RRW_LOCK_HELD(x) \
823b2aab18SMatthew Ahrens 	(rrw_held(x, RW_WRITER) || rrw_held(x, RW_READER))
83f18faf3fSek110237 
8440d689f8SAlexander Motin /*
8540d689f8SAlexander Motin  * A reader-mostly lock implementation, tuning above reader-writer locks
8640d689f8SAlexander Motin  * for hightly parallel read acquisitions, pessimizing write acquisitions.
8740d689f8SAlexander Motin  *
8840d689f8SAlexander Motin  * This should be a prime number.  See comment in rrwlock.c near
8940d689f8SAlexander Motin  * RRM_TD_LOCK() for details.
9040d689f8SAlexander Motin  */
9140d689f8SAlexander Motin #define	RRM_NUM_LOCKS		17
9240d689f8SAlexander Motin typedef struct rrmlock {
9340d689f8SAlexander Motin 	rrwlock_t	locks[RRM_NUM_LOCKS];
9440d689f8SAlexander Motin } rrmlock_t;
9540d689f8SAlexander Motin 
9640d689f8SAlexander Motin void rrm_init(rrmlock_t *rrl, boolean_t track_all);
9740d689f8SAlexander Motin void rrm_destroy(rrmlock_t *rrl);
9840d689f8SAlexander Motin void rrm_enter(rrmlock_t *rrl, krw_t rw, void *tag);
9940d689f8SAlexander Motin void rrm_enter_read(rrmlock_t *rrl, void *tag);
10040d689f8SAlexander Motin void rrm_enter_write(rrmlock_t *rrl);
10140d689f8SAlexander Motin void rrm_exit(rrmlock_t *rrl, void *tag);
10240d689f8SAlexander Motin boolean_t rrm_held(rrmlock_t *rrl, krw_t rw);
10340d689f8SAlexander Motin 
10440d689f8SAlexander Motin #define	RRM_READ_HELD(x)	rrm_held(x, RW_READER)
10540d689f8SAlexander Motin #define	RRM_WRITE_HELD(x)	rrm_held(x, RW_WRITER)
10640d689f8SAlexander Motin #define	RRM_LOCK_HELD(x) \
10740d689f8SAlexander Motin 	(rrm_held(x, RW_WRITER) || rrm_held(x, RW_READER))
10840d689f8SAlexander Motin 
109f18faf3fSek110237 #ifdef	__cplusplus
110f18faf3fSek110237 }
111f18faf3fSek110237 #endif
112f18faf3fSek110237 
113f18faf3fSek110237 #endif	/* _SYS_RR_RW_LOCK_H */
114