summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/sys/machlock.h
blob: e362ca9aba22a8b2c592a37b5f40cefca0a08756 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 * Copyright 2016 Joyent, Inc.
 */

#ifndef _SYS_MACHLOCK_H
#define	_SYS_MACHLOCK_H

#ifndef _ASM
#include <sys/types.h>
#include <sys/time.h>
#endif /* _ASM */

#ifdef	__cplusplus
extern "C" {
#endif

#ifndef	_ASM

#ifdef _KERNEL

extern void	lock_set(lock_t *lp);
extern int	lock_try(lock_t *lp);
extern int	lock_spin_try(lock_t *lp);
extern int	ulock_try(lock_t *lp);
extern void	lock_clear(lock_t *lp);
extern void	ulock_clear(lock_t *lp);
extern void	lock_set_spl(lock_t *lp, int new_pil, ushort_t *old_pil);
extern void	lock_clear_splx(lock_t *lp, int s);

#endif	/* _KERNEL */

#define	LOCK_HELD_VALUE		0xff
#define	LOCK_INIT_CLEAR(lp)	(*(lp) = 0)
#define	LOCK_INIT_HELD(lp)	(*(lp) = LOCK_HELD_VALUE)
#define	LOCK_HELD(lp)		(*(volatile lock_t *)(lp) != 0)

typedef	lock_t	disp_lock_t;		/* dispatcher lock type */

/*
 * SPIN_LOCK() macro indicates whether lock is implemented as a spin lock or
 * an adaptive mutex, depending on what interrupt levels use it.
 */
#define	SPIN_LOCK(pl)	((pl) > ipltospl(LOCK_LEVEL))

/*
 * Macro to control loops which spin on a lock and then check state
 * periodically.  Its passed an integer, and returns a boolean value
 * that if true indicates its a good time to get the scheduler lock and
 * check the state of the current owner of the lock.
 */
#define	LOCK_SAMPLE_INTERVAL(i)	(((i) & 0xff) == 0)

/*
 * Externs for CLOCK_LOCK and clock resolution
 */
extern volatile uint32_t hres_lock;
extern hrtime_t hrtime_base;
extern int clock_res;

#endif	/* _ASM */

/*
 * The definitions of the symbolic interrupt levels:
 *
 *   CLOCK_LEVEL =>  The level at which one must be to block the clock.
 *
 *   LOCK_LEVEL  =>  The highest level at which one may block (and thus the
 *                   highest level at which one may acquire adaptive locks)
 *                   Also the highest level at which one may be preempted.
 *
 *   DISP_LEVEL  =>  The level at which one must be to perform dispatcher
 *                   operations.
 *
 * The constraints on the platform:
 *
 *  - CLOCK_LEVEL must be less than or equal to LOCK_LEVEL
 *  - LOCK_LEVEL must be less than DISP_LEVEL
 *  - DISP_LEVEL should be as close to LOCK_LEVEL as possible
 *
 * Note that LOCK_LEVEL and CLOCK_LEVEL have historically always been equal;
 * changing this relationship is probably possible but not advised.
 *
 */

#define	PIL_MAX		15

#define	CLOCK_LEVEL	10
#define	LOCK_LEVEL	10
#define	DISP_LEVEL	(LOCK_LEVEL + 1)

#define	HIGH_LEVELS	(PIL_MAX - LOCK_LEVEL)

/*
 * The following mask is for the cpu_intr_actv bits corresponding to
 * high-level PILs. It should equal:
 * ((((1 << PIL_MAX + 1) - 1) >> LOCK_LEVEL + 1) << LOCK_LEVEL + 1)
 */
#define	CPU_INTR_ACTV_HIGH_LEVEL_MASK	0xF800

/*
 * The semaphore code depends on being able to represent a lock plus
 * owner in a single 32-bit word.  (Mutexes used to have a similar
 * dependency, but no longer.)  Thus the owner must contain at most
 * 24 significant bits.  At present only threads and semaphores
 * must be aware of this vile constraint.  Different ISAs may handle this
 * differently depending on their capabilities (e.g. compare-and-swap)
 * and limitations (e.g. constraints on alignment and/or KERNELBASE).
 */
#define	PTR24_LSB	5			/* lower bits all zero */
#define	PTR24_MSB	(PTR24_LSB + 24)	/* upper bits all one */
#define	PTR24_ALIGN	32		/* minimum alignment (1 << lsb) */
#define	PTR24_BASE	0xe0000000	/* minimum ptr value (-1 >> (32-msb)) */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_MACHLOCK_H */