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