1*b819cea2SGordon Ross /* 2*b819cea2SGordon Ross * CDDL HEADER START 3*b819cea2SGordon Ross * 4*b819cea2SGordon Ross * The contents of this file are subject to the terms of the 5*b819cea2SGordon Ross * Common Development and Distribution License (the "License"). 6*b819cea2SGordon Ross * You may not use this file except in compliance with the License. 7*b819cea2SGordon Ross * 8*b819cea2SGordon Ross * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*b819cea2SGordon Ross * or http://www.opensolaris.org/os/licensing. 10*b819cea2SGordon Ross * See the License for the specific language governing permissions 11*b819cea2SGordon Ross * and limitations under the License. 12*b819cea2SGordon Ross * 13*b819cea2SGordon Ross * When distributing Covered Code, include this CDDL HEADER in each 14*b819cea2SGordon Ross * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*b819cea2SGordon Ross * If applicable, add the following below this CDDL HEADER, with the 16*b819cea2SGordon Ross * fields enclosed by brackets "[]" replaced with your own identifying 17*b819cea2SGordon Ross * information: Portions Copyright [yyyy] [name of copyright owner] 18*b819cea2SGordon Ross * 19*b819cea2SGordon Ross * CDDL HEADER END 20*b819cea2SGordon Ross */ 21*b819cea2SGordon Ross /* 22*b819cea2SGordon Ross * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. 23*b819cea2SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 24*b819cea2SGordon Ross */ 25*b819cea2SGordon Ross 26*b819cea2SGordon Ross #ifndef _SYS_MUTEX_H 27*b819cea2SGordon Ross #define _SYS_MUTEX_H 28*b819cea2SGordon Ross 29*b819cea2SGordon Ross #include <sys/synch.h> /* lwp_mutex_t */ 30*b819cea2SGordon Ross 31*b819cea2SGordon Ross #ifdef __cplusplus 32*b819cea2SGordon Ross extern "C" { 33*b819cea2SGordon Ross #endif 34*b819cea2SGordon Ross 35*b819cea2SGordon Ross /* 36*b819cea2SGordon Ross * Public interface to mutual exclusion locks. See mutex(9F) for details. 37*b819cea2SGordon Ross * 38*b819cea2SGordon Ross * The basic mutex type is MUTEX_ADAPTIVE, which is expected to be used 39*b819cea2SGordon Ross * in almost all of the kernel. MUTEX_SPIN provides interrupt blocking 40*b819cea2SGordon Ross * and must be used in interrupt handlers above LOCK_LEVEL. The iblock 41*b819cea2SGordon Ross * cookie argument to mutex_init() encodes the interrupt level to block. 42*b819cea2SGordon Ross * The iblock cookie must be NULL for adaptive locks. 43*b819cea2SGordon Ross * 44*b819cea2SGordon Ross * MUTEX_DEFAULT is the type usually specified (except in drivers) to 45*b819cea2SGordon Ross * mutex_init(). It is identical to MUTEX_ADAPTIVE. 46*b819cea2SGordon Ross * 47*b819cea2SGordon Ross * MUTEX_DRIVER is always used by drivers. mutex_init() converts this to 48*b819cea2SGordon Ross * either MUTEX_ADAPTIVE or MUTEX_SPIN depending on the iblock cookie. 49*b819cea2SGordon Ross * 50*b819cea2SGordon Ross * Mutex statistics can be gathered on the fly, without rebooting or 51*b819cea2SGordon Ross * recompiling the kernel, via the lockstat driver (lockstat(7D)). 52*b819cea2SGordon Ross */ 53*b819cea2SGordon Ross typedef enum { 54*b819cea2SGordon Ross MUTEX_ADAPTIVE = 0, /* spin if owner is running, otherwise block */ 55*b819cea2SGordon Ross MUTEX_SPIN = 1, /* block interrupts and spin */ 56*b819cea2SGordon Ross MUTEX_DRIVER = 4, /* driver (DDI) mutex */ 57*b819cea2SGordon Ross MUTEX_DEFAULT = 6 /* kernel default mutex */ 58*b819cea2SGordon Ross } kmutex_type_t; 59*b819cea2SGordon Ross 60*b819cea2SGordon Ross struct _kmutex { 61*b819cea2SGordon Ross lwp_mutex_t m_lock; 62*b819cea2SGordon Ross void *m_owner; 63*b819cea2SGordon Ross }; 64*b819cea2SGordon Ross typedef struct _kmutex kmutex_t; 65*b819cea2SGordon Ross 66*b819cea2SGordon Ross #if defined(_KERNEL) || defined(_FAKE_KERNEL) 67*b819cea2SGordon Ross /* See the real sys/mutex.h */ 68*b819cea2SGordon Ross typedef struct pad_mutex { 69*b819cea2SGordon Ross kmutex_t pad_mutex; 70*b819cea2SGordon Ross #ifdef _LP64 71*b819cea2SGordon Ross char pad_pad[64 - sizeof (kmutex_t)]; 72*b819cea2SGordon Ross #endif 73*b819cea2SGordon Ross } pad_mutex_t; 74*b819cea2SGordon Ross #endif /* _KERNEL */ 75*b819cea2SGordon Ross 76*b819cea2SGordon Ross #define MUTEX_HELD(x) (mutex_owned(x)) 77*b819cea2SGordon Ross #define MUTEX_NOT_HELD(x) (!mutex_owned(x) || panicstr) 78*b819cea2SGordon Ross 79*b819cea2SGordon Ross /* 80*b819cea2SGordon Ross * We're simulating the kernel mutex API here, and the 81*b819cea2SGordon Ross * user-level has a different signature, so rename. 82*b819cea2SGordon Ross */ 83*b819cea2SGordon Ross #define mutex_init kmutex_init 84*b819cea2SGordon Ross #define mutex_destroy kmutex_destroy 85*b819cea2SGordon Ross 86*b819cea2SGordon Ross extern void kmutex_init(kmutex_t *, char *, kmutex_type_t, void *); 87*b819cea2SGordon Ross extern void kmutex_destroy(kmutex_t *); 88*b819cea2SGordon Ross 89*b819cea2SGordon Ross extern void mutex_enter(kmutex_t *); 90*b819cea2SGordon Ross extern int mutex_tryenter(kmutex_t *); 91*b819cea2SGordon Ross extern void mutex_exit(kmutex_t *); 92*b819cea2SGordon Ross extern int mutex_owned(const kmutex_t *); 93*b819cea2SGordon Ross 94*b819cea2SGordon Ross extern void *mutex_owner(const kmutex_t *); 95*b819cea2SGordon Ross 96*b819cea2SGordon Ross #ifdef __cplusplus 97*b819cea2SGordon Ross } 98*b819cea2SGordon Ross #endif 99*b819cea2SGordon Ross 100*b819cea2SGordon Ross #endif /* _SYS_MUTEX_H */ 101