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