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 37#include <ARM/hw_lock_types.h> 38 39extern unsigned int LcksOpts; 40 41#define enaLkDeb 0x00000001 /* Request debug in default attribute */ 42#define enaLkStat 0x00000002 /* Request statistic in default attribute */ 43 44#endif 45 46#ifdef MACH_KERNEL_PRIVATE 47typedef struct { 48 unsigned long interlock; 49 unsigned long lck_spin_pad[9]; /* XXX - usimple_lock_data_t */ 50} lck_spin_t; 51 52#define LCK_SPIN_TAG_DESTROYED 0x00002007 /* lock marked as Destroyed */ 53 54#else 55#ifdef KERNEL_PRIVATE 56typedef struct { 57 unsigned long opaque[10]; 58} lck_spin_t; 59#else 60typedef struct __lck_spin_t__ lck_spin_t; 61#endif 62#endif 63 64#ifdef MACH_KERNEL_PRIVATE 65typedef struct _lck_mtx_ { 66 union { 67 struct { 68 volatile uintptr_t lck_mtxd_owner; 69 unsigned long lck_mtxd_ptr; 70 volatile uint32_t lck_mtxd_waiters:16, 71 lck_mtxd_pri:8, 72 lck_mtxd_ilocked:1, 73 lck_mtxd_mlocked:1, 74 lck_mtxd_promoted:1, 75 lck_mtxd_spin:1, 76 lck_mtxd_pad4:4; /* padding */ 77#ifdef __x86_64__ 78 unsigned int lck_mtxd_pad; 79#endif 80 } lck_mtxd; 81 struct { 82 unsigned long lck_mtxi_tag; 83 struct _lck_mtx_ext_ *lck_mtxi_ptr; 84 unsigned long lck_mtxi_pad; 85 } lck_mtxi; 86 } lck_mtx_sw; 87} lck_mtx_t; 88 89#define lck_mtx_owner lck_mtx_sw.lck_mtxd.lck_mtxd_owner 90#define lck_mtx_waiters lck_mtx_sw.lck_mtxd.lck_mtxd_waiters 91#define lck_mtx_pri lck_mtx_sw.lck_mtxd.lck_mtxd_pri 92#define lck_mtx_ilocked lck_mtx_sw.lck_mtxd.lck_mtxd_ilocked 93#define lck_mtx_mlocked lck_mtx_sw.lck_mtxd.lck_mtxd_mlocked 94#define lck_mtx_promoted lck_mtx_sw.lck_mtxd.lck_mtxd_promoted 95#define lck_mtx_spin lck_mtx_sw.lck_mtxd.lck_mtxd_spin 96 97#define lck_mtx_tag lck_mtx_sw.lck_mtxi.lck_mtxi_tag 98#define lck_mtx_ptr lck_mtx_sw.lck_mtxi.lck_mtxi_ptr 99#define lck_mtx_state lck_mtx_sw.lck_mtxi.lck_mtxi_pad 100 101#define LCK_MTX_TAG_INDIRECT 0x00001007 /* lock marked as Indirect */ 102#define LCK_MTX_TAG_DESTROYED 0x00002007 /* lock marked as Destroyed */ 103#define LCK_MTX_PTR_EXTENDED 0x00003007 /* lock is extended version */ 104 105/* Adaptive spin before blocking */ 106extern unsigned int MutexSpin; 107extern int lck_mtx_lock_spinwait_x86(lck_mtx_t *mutex); 108extern void lck_mtx_lock_wait_x86(lck_mtx_t *mutex); 109extern void lck_mtx_lock_acquire_x86(lck_mtx_t *mutex); 110extern void lck_mtx_unlock_wakeup_x86(lck_mtx_t *mutex, int owner_was_promoted); 111 112extern void lck_mtx_lock_mark_destroyed(lck_mtx_t *mutex); 113extern int lck_mtx_lock_mark_promoted(lck_mtx_t *mutex); 114extern int lck_mtx_lock_decr_waiter(lck_mtx_t *mutex); 115extern int lck_mtx_lock_grab_mutex(lck_mtx_t *mutex); 116extern integer_t lck_mtx_lock_get_pri(lck_mtx_t *mutex); 117 118extern void hw_lock_byte_init(uint8_t *lock_byte); 119extern void hw_lock_byte_lock(uint8_t *lock_byte); 120extern void hw_lock_byte_unlock(uint8_t *lock_byte); 121 122typedef struct { 123 unsigned int type; 124#ifdef __x86_64__ 125 unsigned int pad4; 126#endif 127 vm_offset_t pc; 128 vm_offset_t thread; 129} lck_mtx_deb_t; 130 131#define MUTEX_TAG 0x4d4d 132 133typedef struct { 134 unsigned int lck_mtx_stat_data; 135} lck_mtx_stat_t; 136 137typedef struct _lck_mtx_ext_ { 138 lck_mtx_t lck_mtx; 139 struct _lck_grp_ *lck_mtx_grp; 140 unsigned int lck_mtx_attr; 141#ifdef __x86_64__ 142 unsigned int lck_mtx_pad1; 143#endif 144 lck_mtx_deb_t lck_mtx_deb; 145 uint64_t lck_mtx_stat; 146#ifdef __x86_64__ 147 unsigned int lck_mtx_pad2[2]; 148#endif 149} lck_mtx_ext_t; 150 151#define LCK_MTX_ATTR_DEBUG 0x1 152#define LCK_MTX_ATTR_DEBUGb 0 153#define LCK_MTX_ATTR_STAT 0x2 154#define LCK_MTX_ATTR_STATb 1 155 156#else 157#ifdef KERNEL_PRIVATE 158typedef struct { 159 unsigned long opaque[3]; 160} lck_mtx_t; 161 162typedef struct { 163 unsigned long opaque[10]; 164} lck_mtx_ext_t; 165 166#else 167typedef struct __lck_mtx_t__ lck_mtx_t; 168typedef struct __lck_mtx_ext_t__ lck_mtx_ext_t; 169#endif 170#endif 171 172#ifdef MACH_KERNEL_PRIVATE 173#pragma pack(1) /* Make sure the structure stays as we defined it */ 174typedef struct _lck_rw_t_internal_ { 175 volatile uint16_t lck_rw_shared_count; /* No. of accepted readers */ 176 uint8_t lck_rw_interlock; /* Interlock byte */ 177 volatile uint8_t 178 lck_rw_priv_excl:1, /* Writers prioritized if set */ 179 lck_rw_want_upgrade:1, /* Read-to-write upgrade waiting */ 180 lck_rw_want_write:1, /* Writer waiting or locked for write */ 181 lck_r_waiting:1, /* Reader is sleeping on lock */ 182 lck_w_waiting:1, /* Writer is sleeping on lock */ 183 lck_rw_can_sleep:1, /* Can attempts to lock go to sleep? */ 184 lck_rw_padb6:2; /* padding */ 185 186 uint32_t lck_rw_tag; /* This can be obsoleted when stats 187 * are in 188 */ 189 uint32_t lck_rw_pad8; 190#ifdef __x86_64__ 191 uint32_t lck_rw_pad12; 192#endif 193} lck_rw_t; 194#pragma pack() 195 196#define LCK_RW_ATTR_DEBUG 0x1 197#define LCK_RW_ATTR_DEBUGb 0 198#define LCK_RW_ATTR_STAT 0x2 199#define LCK_RW_ATTR_STATb 1 200#define LCK_RW_ATTR_READ_PRI 0x3 201#define LCK_RW_ATTR_READ_PRIb 2 202#define LCK_RW_ATTR_DIS_THREAD 0x40000000 203#define LCK_RW_ATTR_DIS_THREADb 30 204#define LCK_RW_ATTR_DIS_MYLOCK 0x10000000 205#define LCK_RW_ATTR_DIS_MYLOCKb 28 206 207#define LCK_RW_TAG_DESTROYED 0x00002007 /* lock marked as Destroyed */ 208 209#else 210#ifdef KERNEL_PRIVATE 211#pragma pack(1) 212typedef struct { 213 uint32_t opaque[3]; 214#ifdef __x86_64__ 215 uint32_t opaque4; 216#endif 217} lck_rw_t; 218#pragma pack() 219#else 220typedef struct __lck_rw_t__ lck_rw_t; 221#endif 222#endif 223 224#endif /* _ARM_LOCKS_H_ */ 225