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