]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/lock.h
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (C) 1998 Apple Computer
30 * Mach Operating System
31 * Copyright (c) 1991,1990 Carnegie Mellon University
32 * All Rights Reserved.
34 * Permission to use, copy, modify and distribute this software and its
35 * documentation is hereby granted, provided that both the copyright
36 * notice and this permission notice appear in all copies of the
37 * software, derivative works or modified versions, and any portions
38 * thereof, and that both notices appear in supporting documentation.
40 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
41 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
42 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
44 * Carnegie Mellon requests users of this software to return to
46 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
47 * School of Computer Science
48 * Carnegie Mellon University
49 * Pittsburgh PA 15213-3890
51 * any improvements or extensions that they make and grant Carnegie Mellon
52 * the rights to redistribute these changes.
59 * Machine-dependent simple locks for the i386.
65 #include <sys/appleapiopts.h>
67 #ifdef __APPLE_API_PRIVATE
69 #ifdef MACH_KERNEL_PRIVATE
71 #include <kern/macro_help.h>
72 #include <kern/assert.h>
73 #include <i386/hw_lock_types.h>
76 #include <mach_ldebug.h>
83 * General bit-lock routines.
86 #define bit_lock(bit,l) \
87 __asm__ volatile(" jmp 1f \n \
94 "r" (bit), "m" (*(volatile int *)(l)) : \
97 #define bit_unlock(bit,l) \
98 __asm__ volatile(" lock \n \
101 "r" (bit), "m" (*(volatile int *)(l)));
104 * Set or clear individual bits in a long word.
105 * The locked access is needed only to lock access
106 * to the word, not to individual bits.
109 #define i_bit_set(bit,l) \
110 __asm__ volatile(" lock \n \
113 "r" (bit), "m" (*(volatile int *)(l)));
115 #define i_bit_clear(bit,l) \
116 __asm__ volatile(" lock \n \
119 "r" (bit), "m" (*(volatile int *)(l)));
121 extern __inline__
unsigned long i_bit_isset(unsigned int testbit
, volatile unsigned long *word
)
125 __asm__
volatile("btl %2,%1\n\tsbbl %0,%0" : "=r" (bit
)
126 : "m" (word
), "ir" (testbit
));
130 extern __inline__
char xchgb(volatile char * cp
, char new);
132 extern __inline__
void atomic_incl(long * p
, long delta
);
133 extern __inline__
void atomic_incs(short * p
, short delta
);
134 extern __inline__
void atomic_incb(char * p
, char delta
);
136 extern __inline__
void atomic_decl(long * p
, long delta
);
137 extern __inline__
void atomic_decs(short * p
, short delta
);
138 extern __inline__
void atomic_decb(char * p
, char delta
);
140 extern __inline__
long atomic_getl(long * p
);
141 extern __inline__
short atomic_gets(short * p
);
142 extern __inline__
char atomic_getb(char * p
);
144 extern __inline__
void atomic_setl(long * p
, long value
);
145 extern __inline__
void atomic_sets(short * p
, short value
);
146 extern __inline__
void atomic_setb(char * p
, char value
);
148 extern __inline__
char xchgb(volatile char * cp
, char new)
150 register char old
= new;
152 __asm__
volatile (" xchgb %0,%2" :
154 "0" (new), "m" (*(volatile char *)cp
) : "memory");
158 extern __inline__
void atomic_incl(long * p
, long delta
)
161 __asm__
volatile (" lock \n \
164 "r" (delta
), "m" (*(volatile long *)p
));
165 #else /* NEED_ATOMIC */
167 #endif /* NEED_ATOMIC */
170 extern __inline__
void atomic_incs(short * p
, short delta
)
173 __asm__
volatile (" lock \n \
176 "q" (delta
), "m" (*(volatile short *)p
));
177 #else /* NEED_ATOMIC */
179 #endif /* NEED_ATOMIC */
182 extern __inline__
void atomic_incb(char * p
, char delta
)
185 __asm__
volatile (" lock \n \
188 "q" (delta
), "m" (*(volatile char *)p
));
189 #else /* NEED_ATOMIC */
191 #endif /* NEED_ATOMIC */
194 extern __inline__
void atomic_decl(long * p
, long delta
)
197 __asm__
volatile (" lock \n \
200 "r" (delta
), "m" (*(volatile long *)p
));
201 #else /* NCPUS > 1 */
203 #endif /* NCPUS > 1 */
206 extern __inline__
void atomic_decs(short * p
, short delta
)
209 __asm__
volatile (" lock \n \
212 "q" (delta
), "m" (*(volatile short *)p
));
213 #else /* NEED_ATOMIC */
215 #endif /* NEED_ATOMIC */
218 extern __inline__
void atomic_decb(char * p
, char delta
)
221 __asm__
volatile (" lock \n \
224 "q" (delta
), "m" (*(volatile char *)p
));
225 #else /* NEED_ATOMIC */
227 #endif /* NEED_ATOMIC */
230 extern __inline__
long atomic_getl(long * p
)
235 extern __inline__
short atomic_gets(short * p
)
240 extern __inline__
char atomic_getb(char * p
)
245 extern __inline__
void atomic_setl(long * p
, long value
)
250 extern __inline__
void atomic_sets(short * p
, short value
)
255 extern __inline__
void atomic_setb(char * p
, char value
)
261 #else /* !defined(__GNUC__) */
263 extern void i_bit_set(
267 extern void i_bit_clear(
271 extern void bit_lock(
275 extern void bit_unlock(
280 * All other routines defined in __GNUC__ case lack
281 * definitions otherwise. - XXX
284 #endif /* !defined(__GNUC__) */
287 #if !(USLOCK_DEBUG || USLOCK_STATS)
289 * Take responsibility for production-quality usimple_locks.
290 * Let the portable lock package build simple_locks in terms
291 * of usimple_locks, which is done efficiently with macros.
292 * Currently, these aren't inlined although they probably
293 * should be. The portable lock package is used for the
294 * usimple_lock prototypes and data declarations.
296 * For non-production configurations, punt entirely to the
297 * portable lock package.
299 * N.B. I've left in the hooks for ETAP, so we can
300 * compare the performance of stats-gathering on top
301 * of "production" locks v. stats-gathering on top
302 * of portable, C-based locks.
304 #define USIMPLE_LOCK_CALLS
305 #endif /* !(USLOCK_DEBUG || USLOCK_STATS) */
307 extern void kernel_preempt_check (void);
309 #endif /* MACH_KERNEL_PRIVATE */
311 #endif /* __APLE_API_PRIVATE */
313 #endif /* _I386_LOCK_H_ */