1/* 2 * Copyright (c) 2000 Apple Computer, 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 * @OSF_COPYRIGHT@ 30 * 31 */ 32/* 33 * HISTORY 34 * 35 * Revision 1.1.1.1 1998/09/22 21:05:30 wsanchez 36 * Import of Mac OS X kernel (~semeria) 37 * 38 * Revision 1.1.1.1 1998/03/07 02:25:45 wsanchez 39 * Import of OSF Mach kernel (~mburg) 40 * 41 * Revision 1.1.4.1 1995/06/13 18:20:29 sjs 42 * Merged from flipc_shared. 43 * [95/06/07 sjs] 44 * 45 * Revision 1.1.2.3 1995/03/09 19:42:30 rwd 46 * Move yield function out of macro and prototype. 47 * [1995/03/09 19:36:25 rwd] 48 * 49 * Revision 1.1.2.2 1995/02/21 17:23:11 randys 50 * Re-indented code to four space indentation 51 * [1995/02/21 16:25:39 randys] 52 * 53 * Revision 1.1.2.1 1994/12/20 19:02:06 randys 54 * Moved definition of flipc_simple_lock to flipc_cb.h 55 * [1994/12/20 17:34:44 randys] 56 * 57 * Separated the lock macros out into machine dependent and independent files; 58 * this is the machine independent file. 59 * [1994/12/20 16:43:38 randys] 60 * 61 * $EndLog$ 62 */ 63 64/* 65 * mach/flipc_locks.h 66 * 67 * The machine independent part of the flipc_simple_locks definitions. 68 * Most of the locks definitions is in flipc_dep.h, but what isn't 69 * dependent on the platform being used is here. 70 */ 71 72/* 73 * Note that the locks defined in this file and in flipc_dep.h are only 74 * for use by user level code. The reason why this file is visible to 75 * the kernel is that the kernel section of flipc needs to initialize 76 * these locks. 77 */ 78 79#ifndef _MACH_FLIPC_LOCKS_H_ 80#define _MACH_FLIPC_LOCKS_H_ 81 82/* Get the simple lock type. */ 83#include <mach/flipc_cb.h> 84 85/* 86 * Lock function prototypes. This needs to be before any lock definitions 87 * that happen to be macros. 88 */ 89 90/* Initializes lock. Always a macro (so that kernel code can use it without 91 library assistance). */ 92void flipc_simple_lock_init(flipc_simple_lock *lock); 93 94/* Returns 1 if lock gained, 0 otherwise. */ 95int flipc_simple_lock_try(flipc_simple_lock *lock); 96 97/* Returns 1 if lock is locked, 0 otherwise. */ 98int flipc_simple_lock_locked(flipc_simple_lock *lock); 99 100/* Releases the lock. */ 101void flipc_simple_lock_release(flipc_simple_lock *lock); 102 103/* Take the lock. */ 104void flipc_simple_lock_acquire(flipc_simple_lock *lock); 105 106/* Take two locks. Does not hold one while spinning on the 107 other. */ 108void flipc_simple_lock_acquire_2(flipc_simple_lock *lock1, 109 flipc_simple_lock *lock2); 110 111/* Get the machine dependent stuff. The things that need to be 112 * defined in a machine dependent fashion are: 113 * 114 * flipc_simple_lock_init (must be a macro) 115 * flipc_simple_lock_try 116 * flipc_simple_lock_locked 117 * flipc_simple_lock_release 118 * 119 * These last three don't necessarily have to be macros, but if they 120 * aren't definitions must be included in the machine dependent 121 * part of the user level library code. 122 */ 123#include <mach/machine/flipc_dep.h> 124 125/* 126 * Set at flipc initialization time to thread_yield argument to 127 * FLIPC_domain_init 128 */ 129 130extern void (*flipc_simple_lock_yield_fn)(void); 131 132/* 133 * Machine independent definitions; defined in terms of above routines. 134 */ 135 136/* Take the lock. Assumes an external define saying how long to 137 spin, and an external function to call when we've spun too long. */ 138#define flipc_simple_lock_acquire(lock) \ 139do { \ 140 int __spin_count = 0; \ 141 \ 142 while (flipc_simple_lock_locked(lock) \ 143 || !flipc_simple_lock_try(lock)) \ 144 if (++__spin_count > LOCK_SPIN_LIMIT) { \ 145 (*flipc_simple_lock_yield_fn)(); \ 146 __spin_count = 0; \ 147 } \ 148} while (0) 149 150/* Take two locks. Hold neither while spinning on the other. */ 151#define flipc_simple_lock_acquire_2(lock1, lock2) \ 152do { \ 153 int __spin_count = 0; \ 154 \ 155 while (1) { \ 156 while (flipc_simple_lock_locked(lock1) \ 157 || !flipc_simple_lock_try(lock1)) \ 158 if (++__spin_count > LOCK_SPIN_LIMIT) { \ 159 (*flipc_simple_lock_yield_fn)(); \ 160 __spin_count = 0; \ 161 } \ 162 \ 163 if (flipc_simple_lock_try(lock2)) \ 164 break; \ 165 flipc_simple_lock_release(lock1); \ 166 \ 167 while (flipc_simple_lock_locked(lock2) \ 168 || !flipc_simple_lock_try(lock2)) \ 169 if (++__spin_count > LOCK_SPIN_LIMIT) { \ 170 (*flipc_simple_lock_yield_fn)(); \ 171 __spin_count = 0; \ 172 } \ 173 \ 174 if (flipc_simple_lock_try(lock1)) \ 175 break; \ 176 flipc_simple_lock_release(lock2); \ 177 } \ 178} while (0) 179 180#endif /* _MACH_FLIPC_LOCKS_H_ */ 181