Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
sparc
include
asm
cmpxchg_64.h
Go to the documentation of this file.
1
/* 64-bit atomic xchg() and cmpxchg() definitions.
2
*
3
* Copyright (C) 1996, 1997, 2000 David S. Miller (
[email protected]
)
4
*/
5
6
#ifndef __ARCH_SPARC64_CMPXCHG__
7
#define __ARCH_SPARC64_CMPXCHG__
8
9
static
inline
unsigned
long
xchg32(__volatile__
unsigned
int
*
m
,
unsigned
int
val
)
10
{
11
unsigned
long
tmp1
, tmp2;
12
13
__asm__
__volatile__(
14
" mov %0, %1\n"
15
"1: lduw [%4], %2\n"
16
" cas [%4], %2, %0\n"
17
" cmp %2, %0\n"
18
" bne,a,pn %%icc, 1b\n"
19
" mov %1, %0\n"
20
:
"=&r"
(val),
"=&r"
(tmp1),
"=&r"
(tmp2)
21
:
"0"
(val),
"r"
(m)
22
:
"cc"
,
"memory"
);
23
return
val
;
24
}
25
26
static
inline
unsigned
long
xchg64(__volatile__
unsigned
long
*m,
unsigned
long
val)
27
{
28
unsigned
long
tmp1
, tmp2;
29
30
__asm__
__volatile__(
31
" mov %0, %1\n"
32
"1: ldx [%4], %2\n"
33
" casx [%4], %2, %0\n"
34
" cmp %2, %0\n"
35
" bne,a,pn %%xcc, 1b\n"
36
" mov %1, %0\n"
37
:
"=&r"
(val),
"=&r"
(tmp1),
"=&r"
(tmp2)
38
:
"0"
(val),
"r"
(m)
39
:
"cc"
,
"memory"
);
40
return
val
;
41
}
42
43
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
44
45
extern
void
__xchg_called_with_bad_pointer
(
void
);
46
47
static
inline
unsigned
long
__xchg
(
unsigned
long
x
, __volatile__
void
*
ptr
,
48
int
size
)
49
{
50
switch
(size) {
51
case
4:
52
return
xchg32(ptr, x);
53
case
8:
54
return
xchg64(ptr, x);
55
}
56
__xchg_called_with_bad_pointer
();
57
return
x
;
58
}
59
60
/*
61
* Atomic compare and exchange. Compare OLD with MEM, if identical,
62
* store NEW in MEM. Return the initial value in MEM. Success is
63
* indicated by comparing RETURN with OLD.
64
*/
65
66
#include <
asm-generic/cmpxchg-local.h
>
67
68
#define __HAVE_ARCH_CMPXCHG 1
69
70
static
inline
unsigned
long
71
__cmpxchg_u32
(
volatile
int
*m,
int
old,
int
new
)
72
{
73
__asm__
__volatile__(
"cas [%2], %3, %0"
74
:
"=&r"
(
new
)
75
:
"0"
(
new
),
"r"
(m),
"r"
(old)
76
:
"memory"
);
77
78
return
new
;
79
}
80
81
static
inline
unsigned
long
82
__cmpxchg_u64
(
volatile
long
*m,
unsigned
long
old,
unsigned
long
new
)
83
{
84
__asm__
__volatile__(
"casx [%2], %3, %0"
85
:
"=&r"
(
new
)
86
:
"0"
(
new
),
"r"
(m),
"r"
(old)
87
:
"memory"
);
88
89
return
new
;
90
}
91
92
/* This function doesn't exist, so you'll get a linker error
93
if something tries to do an invalid cmpxchg(). */
94
extern
void
__cmpxchg_called_with_bad_pointer
(
void
);
95
96
static
inline
unsigned
long
97
__cmpxchg
(
volatile
void
*ptr,
unsigned
long
old,
unsigned
long
new
,
int
size)
98
{
99
switch
(size) {
100
case
4:
101
return
__cmpxchg_u32
(ptr, old,
new
);
102
case
8:
103
return
__cmpxchg_u64
(ptr, old,
new
);
104
}
105
__cmpxchg_called_with_bad_pointer
();
106
return
old;
107
}
108
109
#define cmpxchg(ptr,o,n) \
110
({ \
111
__typeof__(*(ptr)) _o_ = (o); \
112
__typeof__(*(ptr)) _n_ = (n); \
113
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
114
(unsigned long)_n_, sizeof(*(ptr))); \
115
})
116
117
/*
118
* cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
119
* them available.
120
*/
121
122
static
inline
unsigned
long
__cmpxchg_local
(
volatile
void
*ptr,
123
unsigned
long
old,
124
unsigned
long
new
,
int
size)
125
{
126
switch
(size) {
127
case
4:
128
case
8:
return
__cmpxchg
(ptr, old,
new
, size);
129
default
:
130
return
__cmpxchg_local_generic(ptr, old,
new
, size);
131
}
132
133
return
old;
134
}
135
136
#define cmpxchg_local(ptr, o, n) \
137
((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
138
(unsigned long)(n), sizeof(*(ptr))))
139
#define cmpxchg64_local(ptr, o, n) \
140
({ \
141
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
142
cmpxchg_local((ptr), (o), (n)); \
143
})
144
145
#endif
/* __ARCH_SPARC64_CMPXCHG__ */
Generated on Thu Jan 10 2013 13:18:07 for Linux Kernel by
1.8.2