1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_LOCKSTAT_H 27 #define _SYS_LOCKSTAT_H 28 29 #include <sys/dtrace.h> 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #define LS_MUTEX_ENTER_ACQUIRE 0 36 #define LS_MUTEX_ENTER_BLOCK 1 37 #define LS_MUTEX_ENTER_SPIN 2 38 #define LS_MUTEX_EXIT_RELEASE 3 39 #define LS_MUTEX_DESTROY_RELEASE 4 40 #define LS_MUTEX_TRYENTER_ACQUIRE 5 41 #define LS_LOCK_SET_ACQUIRE 6 42 #define LS_LOCK_SET_SPIN 7 43 #define LS_LOCK_SET_SPL_ACQUIRE 8 44 #define LS_LOCK_SET_SPL_SPIN 9 45 #define LS_LOCK_TRY_ACQUIRE 10 46 #define LS_LOCK_CLEAR_RELEASE 11 47 #define LS_LOCK_CLEAR_SPLX_RELEASE 12 48 #define LS_CLOCK_UNLOCK_RELEASE 13 49 #define LS_RW_ENTER_ACQUIRE 14 50 #define LS_RW_ENTER_BLOCK 15 51 #define LS_RW_EXIT_RELEASE 16 52 #define LS_RW_TRYENTER_ACQUIRE 17 53 #define LS_RW_TRYUPGRADE_UPGRADE 18 54 #define LS_RW_DOWNGRADE_DOWNGRADE 19 55 #define LS_THREAD_LOCK_ACQUIRE 20 56 #define LS_THREAD_LOCK_SPIN 21 57 #define LS_THREAD_LOCK_HIGH_ACQUIRE 22 58 #define LS_THREAD_LOCK_HIGH_SPIN 23 59 #define LS_TURNSTILE_INTERLOCK_SPIN 24 60 #define LS_NPROBES 25 61 62 #define LS_MUTEX_ENTER "mutex_enter" 63 #define LS_MUTEX_EXIT "mutex_exit" 64 #define LS_MUTEX_DESTROY "mutex_destroy" 65 #define LS_MUTEX_TRYENTER "mutex_tryenter" 66 #define LS_LOCK_SET "lock_set" 67 #define LS_LOCK_SET_SPL "lock_set_spl" 68 #define LS_LOCK_TRY "lock_try" 69 #define LS_LOCK_CLEAR "lock_clear" 70 #define LS_LOCK_CLEAR_SPLX "lock_clear_splx" 71 #define LS_CLOCK_UNLOCK "CLOCK_UNLOCK" 72 #define LS_RW_ENTER "rw_enter" 73 #define LS_RW_EXIT "rw_exit" 74 #define LS_RW_TRYENTER "rw_tryenter" 75 #define LS_RW_TRYUPGRADE "rw_tryupgrade" 76 #define LS_RW_DOWNGRADE "rw_downgrade" 77 #define LS_THREAD_LOCK "thread_lock" 78 #define LS_THREAD_LOCK_HIGH "thread_lock_high" 79 80 #define LS_ACQUIRE "acquire" 81 #define LS_RELEASE "release" 82 #define LS_SPIN "spin" 83 #define LS_BLOCK "block" 84 #define LS_UPGRADE "upgrade" 85 #define LS_DOWNGRADE "downgrade" 86 87 #define LS_TYPE_ADAPTIVE "adaptive" 88 #define LS_TYPE_SPIN "spin" 89 #define LS_TYPE_THREAD "thread" 90 #define LS_TYPE_RW "rw" 91 92 #define LSA_ACQUIRE (LS_TYPE_ADAPTIVE "-" LS_ACQUIRE) 93 #define LSA_RELEASE (LS_TYPE_ADAPTIVE "-" LS_RELEASE) 94 #define LSA_SPIN (LS_TYPE_ADAPTIVE "-" LS_SPIN) 95 #define LSA_BLOCK (LS_TYPE_ADAPTIVE "-" LS_BLOCK) 96 #define LSS_ACQUIRE (LS_TYPE_SPIN "-" LS_ACQUIRE) 97 #define LSS_RELEASE (LS_TYPE_SPIN "-" LS_RELEASE) 98 #define LSS_SPIN (LS_TYPE_SPIN "-" LS_SPIN) 99 #define LSR_ACQUIRE (LS_TYPE_RW "-" LS_ACQUIRE) 100 #define LSR_RELEASE (LS_TYPE_RW "-" LS_RELEASE) 101 #define LSR_BLOCK (LS_TYPE_RW "-" LS_BLOCK) 102 #define LSR_UPGRADE (LS_TYPE_RW "-" LS_UPGRADE) 103 #define LSR_DOWNGRADE (LS_TYPE_RW "-" LS_DOWNGRADE) 104 #define LST_SPIN (LS_TYPE_THREAD "-" LS_SPIN) 105 106 #ifndef _ASM 107 108 #include <sys/types.h> 109 #include <sys/inttypes.h> 110 #include <sys/systm.h> 111 #include <sys/atomic.h> 112 113 #ifdef _KERNEL 114 115 /* 116 * Platform-independent kernel support for the lockstat driver. 117 */ 118 extern dtrace_id_t lockstat_probemap[LS_NPROBES]; 119 extern void (*lockstat_probe)(dtrace_id_t, uintptr_t, uintptr_t, 120 uintptr_t, uintptr_t, uintptr_t); 121 122 extern int lockstat_active_threads(void); 123 extern int lockstat_depth(void); 124 extern void lockstat_hotpatch_probe(int); 125 126 /* 127 * Macros to record lockstat probes. 128 */ 129 130 /* used for 32 bit systems to avoid overflow */ 131 #if defined(_ILP32) 132 #define CLAMP32(x) ((x) > UINT_MAX ? UINT_MAX : (x)) 133 #else 134 #define CLAMP32(x) (x) 135 #endif 136 137 #define LOCKSTAT_RECORD4(probe, lp, arg0, arg1, arg2, arg3) \ 138 if (lockstat_probemap[(probe)]) { \ 139 dtrace_id_t id; \ 140 curthread->t_lockstat++; \ 141 membar_enter(); \ 142 if ((id = lockstat_probemap[(probe)]) != 0) \ 143 (*lockstat_probe)(id, (uintptr_t)(lp), (arg0), \ 144 (arg1), (arg2), (arg3)); \ 145 curthread->t_lockstat--; \ 146 } 147 148 #define LOCKSTAT_RECORD(probe, lp, arg) \ 149 LOCKSTAT_RECORD4(probe, lp, arg, 0, 0, 0) 150 151 #define LOCKSTAT_RECORD0(probe, lp) \ 152 LOCKSTAT_RECORD4(probe, lp, 0, 0, 0, 0) 153 154 /* 155 * Return timestamp for start of busy-waiting (for spin probes) 156 */ 157 #define LOCKSTAT_START_TIME(probe) ( \ 158 lockstat_probemap[(probe)] ? gethrtime_waitfree() : 0 \ 159 ) 160 161 /* 162 * Record elapsed time since LOCKSTAT_START_TIME was called if the 163 * probe is enabled at start and end, else return 0. t_start must 164 * be the value returned by LOCKSTAT_START_TIME. 165 */ 166 #define LOCKSTAT_RECORD_TIME(probe, lp, t_start) \ 167 if (lockstat_probemap[(probe)]) { \ 168 dtrace_id_t id; \ 169 hrtime_t t_spin = (t_start); \ 170 curthread->t_lockstat++; \ 171 membar_enter(); \ 172 if ((id = lockstat_probemap[(probe)]) != 0) { \ 173 if (t_spin) { \ 174 t_spin = gethrtime_waitfree() - t_spin; \ 175 t_spin = CLAMP32(t_spin); \ 176 } \ 177 (*lockstat_probe)(id, (uintptr_t)(lp), t_spin, \ 178 0, 0, 0); \ 179 } \ 180 curthread->t_lockstat--; \ 181 } 182 183 184 #endif /* _KERNEL */ 185 186 #endif /* _ASM */ 187 188 #ifdef __cplusplus 189 } 190 #endif 191 192 #endif /* _SYS_LOCKSTAT_H */ 193