1/*
2 * Copyright (c) 2004-2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef	_ARM_LOCKS_H_
30#define	_ARM_LOCKS_H_
31
32#include <sys/appleapiopts.h>
33#include <kern/kern_types.h>
34
35#ifdef	MACH_KERNEL_PRIVATE
36
37struct hslock {
38    uintptr_t lock_data;
39};
40typedef struct hslock hw_lock_data_t, *hw_lock_t;
41
42extern unsigned int LcksOpts;
43
44#define enaLkDeb		0x00000001  /* Request debug in default attribute */
45#define enaLkStat		0x00000002  /* Request statistic in default attribute */
46
47#endif
48
49#ifdef	MACH_KERNEL_PRIVATE
50typedef struct {
51    unsigned long interlock;
52    unsigned long lck_spin_pad[9];  /* XXX - usimple_lock_data_t */
53} lck_spin_t;
54
55#define	LCK_SPIN_TAG_DESTROYED		0x00002007  /* lock marked as Destroyed */
56
57#else
58#ifdef	KERNEL_PRIVATE
59typedef struct {
60    unsigned long opaque[10];
61} lck_spin_t;
62#else
63typedef struct __lck_spin_t__ lck_spin_t;
64#endif
65#endif
66
67#ifdef	MACH_KERNEL_PRIVATE
68typedef struct _lck_mtx_ {
69    union {
70        struct {
71            unsigned int lck_mtxd_data;
72            unsigned short lck_mtxd_waiters;
73            unsigned short lck_mtxd_pri;
74            unsigned int lck_mtxd_pad8;
75        } lck_mtxd;
76        struct {
77            unsigned int lck_mtxi_tag;
78            struct _lck_mtx_ext_ *lck_mtxi_ptr;
79            unsigned int lck_mtxi_pad;
80        } lck_mtxi;
81    } lck_mtx_sw;
82} lck_mtx_t;
83
84#define lck_mtx_data    lck_mtx_sw.lck_mtxd.lck_mtxd_data
85#define	lck_mtx_owner	lck_mtx_sw.lck_mtxd.lck_mtxd_owner
86#define	lck_mtx_waiters	lck_mtx_sw.lck_mtxd.lck_mtxd_waiters
87#define	lck_mtx_pri	lck_mtx_sw.lck_mtxd.lck_mtxd_pri
88#define	lck_mtx_ilocked	lck_mtx_sw.lck_mtxd.lck_mtxd_ilocked
89#define	lck_mtx_mlocked	lck_mtx_sw.lck_mtxd.lck_mtxd_mlocked
90#define	lck_mtx_promoted lck_mtx_sw.lck_mtxd.lck_mtxd_promoted
91#define	lck_mtx_spin	lck_mtx_sw.lck_mtxd.lck_mtxd_spin
92
93#define lck_mtx_tag	lck_mtx_sw.lck_mtxi.lck_mtxi_tag
94#define lck_mtx_ptr	lck_mtx_sw.lck_mtxi.lck_mtxi_ptr
95#define lck_mtx_state	lck_mtx_sw.lck_mtxi.lck_mtxi_pad
96
97#define	LCK_MTX_TAG_INDIRECT			0x00001007  /* lock marked as Indirect  */
98#define	LCK_MTX_TAG_DESTROYED			0x00002007  /* lock marked as Destroyed */
99#define LCK_MTX_PTR_EXTENDED			0x00003007  /* lock is extended version */
100
101/* Adaptive spin before blocking */
102extern unsigned int MutexSpin;
103
104extern void lck_mtx_lock_mark_destroyed(lck_mtx_t * mutex);
105extern int lck_mtx_lock_mark_promoted(lck_mtx_t * mutex);
106extern int lck_mtx_lock_decr_waiter(lck_mtx_t * mutex);
107extern int lck_mtx_lock_grab_mutex(lck_mtx_t * mutex);
108extern integer_t lck_mtx_lock_get_pri(lck_mtx_t * mutex);
109
110extern void hw_lock_byte_init(uint8_t * lock_byte);
111extern void hw_lock_byte_lock(uint8_t * lock_byte);
112extern void hw_lock_byte_unlock(uint8_t * lock_byte);
113
114#define     lck_rw_lock_exclusive       lck_rw_lock_exclusive_gen
115
116typedef struct {
117    unsigned int type;
118    vm_offset_t pc;
119    vm_offset_t thread;
120} lck_mtx_deb_t;
121
122#define MUTEX_TAG       0x4d4d
123
124typedef struct {
125    unsigned int lck_mtx_stat_data;
126} lck_mtx_stat_t;
127
128typedef struct _lck_mtx_ext_ {
129    lck_mtx_t lck_mtx;
130    struct _lck_grp_ *lck_mtx_grp;
131    unsigned int lck_mtx_attr;
132    lck_mtx_deb_t lck_mtx_deb;
133    uint64_t lck_mtx_stat;
134} lck_mtx_ext_t;
135
136#define	LCK_MTX_ATTR_DEBUG	0x1
137#define	LCK_MTX_ATTR_DEBUGb	0
138#define	LCK_MTX_ATTR_STAT	0x2
139#define	LCK_MTX_ATTR_STATb	1
140
141#else
142#ifdef	KERNEL_PRIVATE
143typedef struct {
144    unsigned long opaque[3];
145} lck_mtx_t;
146
147typedef struct {
148    unsigned long opaque[10];
149} lck_mtx_ext_t;
150
151#else
152typedef struct __lck_mtx_t__ lck_mtx_t;
153typedef struct __lck_mtx_ext_t__ lck_mtx_ext_t;
154#endif
155#endif
156
157#ifdef	MACH_KERNEL_PRIVATE
158#pragma pack(1)                 /* Make sure the structure stays as we defined it */
159typedef struct _lck_rw_t_internal_ {
160    union {
161        struct {
162            unsigned int lck_rwd_interlock:1, lck_rwd_waiting:1,
163                lck_rwd_want_upgrade:1, lck_rwd_want_excl:1, lck_rwd_pad17:11,
164                lck_rwd_priv_excl:1, lck_rwd_shared_cnt:16;
165            unsigned int lck_rwd_pad4;
166            unsigned int lck_rwd_pad8;
167        } lck_rwd;
168        struct {
169            unsigned int lck_rwi_tag;
170            struct _lck_rw_ext_ *lck_rwi_ptr;
171            unsigned int lck_rwi_pad8;
172        } lck_rwi;
173    } lck_rw_sw;
174} lck_rw_t;
175
176#define	lck_rw_interlock		lck_rw_sw.lck_rwd.lck_rwd_interlock
177#define	lck_rw_want_upgrade		lck_rw_sw.lck_rwd.lck_rwd_want_upgrade
178#define	lck_rw_want_excl		lck_rw_sw.lck_rwd.lck_rwd_want_excl
179#define	lck_rw_waiting			lck_rw_sw.lck_rwd.lck_rwd_waiting
180#define	lck_rw_priv_excl		lck_rw_sw.lck_rwd.lck_rwd_priv_excl
181#define	lck_rw_shared_count		lck_rw_sw.lck_rwd.lck_rwd_shared_cnt
182
183#define lck_rw_tag				lck_rw_sw.lck_rwi.lck_rwi_tag
184#define lck_rw_ptr				lck_rw_sw.lck_rwi.lck_rwi_ptr
185
186#pragma pack()
187
188#define	LCK_RW_ATTR_DEBUG	0x1
189#define	LCK_RW_ATTR_DEBUGb	0
190#define	LCK_RW_ATTR_STAT	0x2
191#define	LCK_RW_ATTR_STATb	1
192#define LCK_RW_ATTR_READ_PRI	0x3
193#define LCK_RW_ATTR_READ_PRIb	2
194#define	LCK_RW_ATTR_DIS_THREAD	0x40000000
195#define	LCK_RW_ATTR_DIS_THREADb	30
196#define	LCK_RW_ATTR_DIS_MYLOCK	0x10000000
197#define	LCK_RW_ATTR_DIS_MYLOCKb	28
198
199#define	LCK_RW_TAG_DESTROYED		0x00002007  /* lock marked as Destroyed */
200
201#else
202#ifdef	KERNEL_PRIVATE
203#pragma pack(1)
204typedef struct {
205    uint32_t opaque[3];
206} lck_rw_t;
207#pragma pack()
208#else
209typedef struct __lck_rw_t__ lck_rw_t;
210#endif
211#endif
212
213#endif                          /* _ARM_LOCKS_H_ */
214