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 (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #ifndef _SYS_MUTEX_H 26 #define _SYS_MUTEX_H 27 28 #ifndef _ASM 29 #include <sys/types.h> 30 #endif 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 #ifndef _ASM 37 38 /* 39 * Public interface to mutual exclusion locks. See mutex(9F) for details. 40 * 41 * The basic mutex type is MUTEX_ADAPTIVE, which is expected to be used 42 * in almost all of the kernel. MUTEX_SPIN provides interrupt blocking 43 * and must be used in interrupt handlers above LOCK_LEVEL. The iblock 44 * cookie argument to mutex_init() encodes the interrupt level to block. 45 * The iblock cookie must be NULL for adaptive locks. 46 * 47 * MUTEX_DEFAULT is the type usually specified (except in drivers) to 48 * mutex_init(). It is identical to MUTEX_ADAPTIVE. 49 * 50 * MUTEX_DRIVER is always used by drivers. mutex_init() converts this to 51 * either MUTEX_ADAPTIVE or MUTEX_SPIN depending on the iblock cookie. 52 * 53 * Mutex statistics can be gathered on the fly, without rebooting or 54 * recompiling the kernel, via the lockstat driver (lockstat(4D)). 55 */ 56 typedef enum { 57 MUTEX_ADAPTIVE = 0, /* spin if owner is running, otherwise block */ 58 MUTEX_SPIN = 1, /* block interrupts and spin */ 59 MUTEX_DRIVER = 4, /* driver (DDI) mutex */ 60 MUTEX_DEFAULT = 6 /* kernel default mutex */ 61 } kmutex_type_t; 62 63 typedef struct mutex { 64 #ifdef _LP64 65 void *_opaque[1]; 66 #else 67 void *_opaque[2]; 68 #endif 69 } kmutex_t; 70 71 #ifdef _KERNEL 72 73 /* 74 * A padded mutex, one per 64 byte cache line. Use when false sharing is 75 * an issue but beware of the extra memory it uses. Consumers may want to 76 * consider aligning their pad_mutex_t's to a cache line boundary as well. 77 */ 78 typedef struct pad_mutex { 79 kmutex_t pad_mutex; 80 #ifdef _LP64 81 char pad_pad[64 - sizeof (kmutex_t)]; 82 #endif 83 } pad_mutex_t; 84 85 #define MUTEX_HELD(x) (mutex_owned(x)) 86 #define MUTEX_NOT_HELD(x) (!mutex_owned(x) || panicstr || quiesce_active) 87 88 extern void mutex_init(kmutex_t *, char *, kmutex_type_t, void *); 89 extern void mutex_destroy(kmutex_t *); 90 extern void mutex_enter(kmutex_t *); 91 extern int mutex_tryenter(kmutex_t *); 92 extern void mutex_exit(kmutex_t *); 93 extern int mutex_owned(const kmutex_t *); 94 extern struct _kthread *mutex_owner(const kmutex_t *); 95 96 extern ushort_t mutex_backoff_base; 97 extern uint_t mutex_backoff_cap; 98 extern ushort_t mutex_cap_factor; 99 extern uchar_t mutex_backoff_shift; 100 extern void (*mutex_lock_delay)(uint_t); 101 extern uint_t (*mutex_lock_backoff)(uint_t); 102 extern void (*mutex_delay)(void); 103 extern void mutex_delay_default(void); 104 extern void mutex_sync(void); 105 106 extern void default_lock_delay(uint_t); 107 extern uint_t default_lock_backoff(uint_t); 108 109 #endif /* _KERNEL */ 110 111 #endif /* _ASM */ 112 113 #ifdef __cplusplus 114 } 115 #endif 116 117 #endif /* _SYS_MUTEX_H */ 118