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 _I386_LOCKS_H_ 30#define _I386_LOCKS_H_ 31 32#include <sys/appleapiopts.h> 33#include <kern/kern_types.h> 34 35#ifdef MACH_KERNEL_PRIVATE 36 37#include <i386/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 /* MACH_KERNEL_PRIVATE */ 45 46#if defined(MACH_KERNEL_PRIVATE) 47typedef struct { 48 volatile uintptr_t interlock; 49#if MACH_LDEBUG 50 unsigned long lck_spin_pad[9]; /* XXX - usimple_lock_data_t */ 51#endif 52} lck_spin_t; 53 54#define LCK_SPIN_TAG_DESTROYED 0x00002007 /* lock marked as Destroyed */ 55 56#else /* MACH_KERNEL_PRIVATE */ 57#ifdef KERNEL_PRIVATE 58typedef struct { 59 unsigned long opaque[10]; 60} lck_spin_t; 61#else /* KERNEL_PRIVATE */ 62typedef struct __lck_spin_t__ lck_spin_t; 63#endif 64#endif 65 66#ifdef MACH_KERNEL_PRIVATE 67/* The definition of this structure, including the layout of the 68 * state bitfield, is tailored to the asm implementation in i386_lock.s 69 */ 70typedef struct _lck_mtx_ { 71 union { 72 struct { 73 volatile uintptr_t lck_mtxd_owner; 74 union { 75 struct { 76 volatile uint32_t 77 lck_mtxd_waiters:16, 78 lck_mtxd_pri:8, 79 lck_mtxd_ilocked:1, 80 lck_mtxd_mlocked:1, 81 lck_mtxd_promoted:1, 82 lck_mtxd_spin:1, 83 lck_mtxd_is_ext:1, 84 lck_mtxd_pad3:3; 85 }; 86 uint32_t lck_mtxd_state; 87 }; 88#if defined(__x86_64__) 89 /* Pad field used as a canary, initialized to ~0 */ 90 uint32_t lck_mtxd_pad32; 91#endif 92 } lck_mtxd; 93 struct { 94 struct _lck_mtx_ext_ *lck_mtxi_ptr; 95 uint32_t lck_mtxi_tag; 96#if defined(__x86_64__) 97 uint32_t lck_mtxi_pad32; 98#endif 99 } lck_mtxi; 100 } lck_mtx_sw; 101} lck_mtx_t; 102 103#define lck_mtx_owner lck_mtx_sw.lck_mtxd.lck_mtxd_owner 104#define lck_mtx_waiters lck_mtx_sw.lck_mtxd.lck_mtxd_waiters 105#define lck_mtx_pri lck_mtx_sw.lck_mtxd.lck_mtxd_pri 106#define lck_mtx_promoted lck_mtx_sw.lck_mtxd.lck_mtxd_promoted 107#define lck_mtx_is_ext lck_mtx_sw.lck_mtxd.lck_mtxd_is_ext 108 109#define lck_mtx_tag lck_mtx_sw.lck_mtxi.lck_mtxi_tag 110#define lck_mtx_ptr lck_mtx_sw.lck_mtxi.lck_mtxi_ptr 111#define lck_mtx_state lck_mtx_sw.lck_mtxd.lck_mtxd_state 112/* This pattern must subsume the interlocked, mlocked and spin bits */ 113#define LCK_MTX_TAG_INDIRECT 0x07ff1007 /* lock marked as Indirect */ 114#define LCK_MTX_TAG_DESTROYED 0x07fe2007 /* lock marked as Destroyed */ 115 116/* Adaptive spin before blocking */ 117extern unsigned int MutexSpin; 118extern int lck_mtx_lock_spinwait_x86(lck_mtx_t *mutex); 119extern void lck_mtx_lock_wait_x86(lck_mtx_t *mutex); 120extern void lck_mtx_lock_acquire_x86(lck_mtx_t *mutex); 121extern void lck_mtx_unlock_wakeup_x86(lck_mtx_t *mutex, int prior_lock_state); 122 123extern void lck_mtx_lock_mark_destroyed(lck_mtx_t *mutex); 124extern int lck_mtx_lock_grab_mutex(lck_mtx_t *mutex); 125 126extern void hw_lock_byte_init(volatile uint8_t *lock_byte); 127extern void hw_lock_byte_lock(volatile uint8_t *lock_byte); 128extern void hw_lock_byte_unlock(volatile uint8_t *lock_byte); 129 130typedef struct { 131 unsigned int type; 132#ifdef __x86_64__ 133 unsigned int pad4; 134#endif 135 vm_offset_t pc; 136 vm_offset_t thread; 137} lck_mtx_deb_t; 138 139#define MUTEX_TAG 0x4d4d 140 141typedef struct { 142 unsigned int lck_mtx_stat_data; 143} lck_mtx_stat_t; 144 145typedef struct _lck_mtx_ext_ { 146 lck_mtx_t lck_mtx; 147 struct _lck_grp_ *lck_mtx_grp; 148 unsigned int lck_mtx_attr; 149#ifdef __x86_64__ 150 unsigned int lck_mtx_pad1; 151#endif 152 lck_mtx_deb_t lck_mtx_deb; 153 uint64_t lck_mtx_stat; 154#ifdef __x86_64__ 155 unsigned int lck_mtx_pad2[2]; 156#endif 157} lck_mtx_ext_t; 158 159#define LCK_MTX_ATTR_DEBUG 0x1 160#define LCK_MTX_ATTR_DEBUGb 0 161#define LCK_MTX_ATTR_STAT 0x2 162#define LCK_MTX_ATTR_STATb 1 163 164#else /* MACH_KERNEL_PRIVATE */ 165#ifdef XNU_KERNEL_PRIVATE 166typedef struct { 167 unsigned long opaque[2]; 168} lck_mtx_t; 169 170typedef struct { 171 unsigned long opaque[10]; 172} lck_mtx_ext_t; 173#else 174#ifdef KERNEL_PRIVATE 175typedef struct { 176 unsigned long opaque[2]; 177} lck_mtx_t; 178 179typedef struct { 180 unsigned long opaque[10]; 181} lck_mtx_ext_t; 182 183#else 184typedef struct __lck_mtx_t__ lck_mtx_t; 185typedef struct __lck_mtx_ext_t__ lck_mtx_ext_t; 186#endif 187#endif 188#endif 189 190#ifdef MACH_KERNEL_PRIVATE 191#pragma pack(1) /* Make sure the structure stays as we defined it */ 192typedef struct _lck_rw_t_internal_ { 193 volatile uint16_t lck_rw_shared_count; /* No. of accepted readers */ 194 volatile uint8_t lck_rw_interlock; /* Interlock byte */ 195 volatile uint8_t 196 lck_rw_priv_excl:1, /* Writers prioritized if set */ 197 lck_rw_want_upgrade:1, /* Read-to-write upgrade waiting */ 198 lck_rw_want_write:1, /* Writer waiting or locked for write */ 199 lck_r_waiting:1, /* Reader is sleeping on lock */ 200 lck_w_waiting:1, /* Writer is sleeping on lock */ 201 lck_rw_can_sleep:1, /* Can attempts to lock go to sleep? */ 202 lck_rw_padb6:2; /* padding */ 203 204 uint32_t lck_rw_tag; /* This can be obsoleted when stats 205 * are in 206 */ 207 uint32_t lck_rw_pad8; 208#ifdef __x86_64__ 209 uint32_t lck_rw_pad12; 210#endif 211} lck_rw_t; 212#pragma pack() 213 214#define LCK_RW_ATTR_DEBUG 0x1 215#define LCK_RW_ATTR_DEBUGb 0 216#define LCK_RW_ATTR_STAT 0x2 217#define LCK_RW_ATTR_STATb 1 218#define LCK_RW_ATTR_READ_PRI 0x3 219#define LCK_RW_ATTR_READ_PRIb 2 220#define LCK_RW_ATTR_DIS_THREAD 0x40000000 221#define LCK_RW_ATTR_DIS_THREADb 30 222#define LCK_RW_ATTR_DIS_MYLOCK 0x10000000 223#define LCK_RW_ATTR_DIS_MYLOCKb 28 224 225#define LCK_RW_TAG_DESTROYED 0x00002007 /* lock marked as Destroyed */ 226 227#else 228#ifdef KERNEL_PRIVATE 229#pragma pack(1) 230typedef struct { 231 uint32_t opaque[3]; 232#ifdef __x86_64__ 233 uint32_t opaque4; 234#endif 235} lck_rw_t; 236#pragma pack() 237#else 238typedef struct __lck_rw_t__ lck_rw_t; 239#endif 240#endif 241 242#endif /* _I386_LOCKS_H_ */ 243