FreeBSD/Linux Kernel Cross Reference
sys/i386/lock.h
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26
27 /*
28 * HISTORY
29 * $Log: lock.h,v $
30 * Revision 2.4 91/11/12 11:50:47 rvb
31 * Added simple_lock_pause.
32 * [91/11/12 rpd]
33 *
34 * Revision 2.3 91/05/14 16:11:00 mrt
35 * Correcting copyright
36 *
37 * Revision 2.2 91/05/08 12:39:08 dbg
38 * Created.
39 * [91/03/21 dbg]
40 *
41 */
42
43 /*
44 * Machine-dependent simple locks for the i386.
45 */
46 #ifndef _I386_LOCK_H_
47 #define _I386_LOCK_H_
48
49 /*
50 * All of the locking routines are built from calls on
51 * a locked-exchange operation. Values of the lock are
52 * 0 for unlocked, 1 for locked.
53 */
54
55 #ifdef __GNUC__
56
57 /*
58 * The code here depends on the GNU C compiler.
59 */
60
61 #define _simple_lock_xchg_(lock, new_val) \
62 ({ register int _old_val_; \
63 asm volatile("xchgl %0, %2" \
64 : "=r" (_old_val_) \
65 : "" (new_val), "m" (*(lock)) \
66 ); \
67 _old_val_; \
68 })
69
70 #define simple_lock_init(l) \
71 ((l)->lock_data = 0)
72
73 #define simple_lock(l) \
74 ({ \
75 while(_simple_lock_xchg_(l, 1)) \
76 while (*(volatile int *)&(l)->lock_data) \
77 continue; \
78 0; \
79 })
80
81 #define simple_unlock(l) \
82 (_simple_lock_xchg_(l, 0))
83
84 #define simple_lock_try(l) \
85 (!_simple_lock_xchg_(l, 1))
86
87 /*
88 * General bit-lock routines.
89 */
90 #define bit_lock(bit, l) \
91 ({ \
92 asm volatile(" jmp 1f \n\
93 0: btl %0, %1 \n\
94 jb 0b \n\
95 1: lock \n\
96 btsl %0, %1 \n\
97 jb 0b" \
98 : \
99 : "r" (bit), "m" (*(volatile int *)(l))); \
100 0; \
101 })
102
103 #define bit_unlock(bit, l) \
104 ({ \
105 asm volatile(" lock \n\
106 btrl %0, %1" \
107 : \
108 : "r" (bit), "m" (*(volatile int *)(l))); \
109 0; \
110 })
111
112 /*
113 * Set or clear individual bits in a long word.
114 * The locked access is needed only to lock access
115 * to the word, not to individual bits.
116 */
117 #define i_bit_set(bit, l) \
118 ({ \
119 asm volatile(" lock \n\
120 btsl %0, %1" \
121 : \
122 : "r" (bit), "m" (*(l)) ); \
123 0; \
124 })
125
126 #define i_bit_clear(bit, l) \
127 ({ \
128 asm volatile(" lock \n\
129 btrl %0, %1" \
130 : \
131 : "r" (bit), "m" (*(l)) ); \
132 0; \
133 })
134
135 #endif /* __GNUC__ */
136
137 extern void simple_lock_pause();
138
139 #endif /* _I386_LOCK_H_ */
Cache object: c3d9f23e8951d014cef95a959fe51e7c
|