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