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
avr32
include
asm
cmpxchg.h
Go to the documentation of this file.
1
/*
2
* Atomic operations that C can't guarantee us. Useful for
3
* resource counting etc.
4
*
5
* But use these as seldom as possible since they are slower than
6
* regular operations.
7
*
8
* Copyright (C) 2004-2006 Atmel Corporation
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License version 2 as
12
* published by the Free Software Foundation.
13
*/
14
#ifndef __ASM_AVR32_CMPXCHG_H
15
#define __ASM_AVR32_CMPXCHG_H
16
17
#define xchg(ptr,x) \
18
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
19
20
extern
void
__xchg_called_with_bad_pointer
(
void
);
21
22
static
inline
unsigned
long
xchg_u32(
u32
val
,
volatile
u32
*
m
)
23
{
24
u32
ret
;
25
26
asm
volatile
(
"xchg %[ret], %[m], %[val]"
27
: [
ret
]
"=&r"
(
ret
),
"=m"
(*m)
28
:
"m"
(*m), [
m
]
"r"
(
m
), [val]
"r"
(val)
29
:
"memory"
);
30
return
ret
;
31
}
32
33
static
inline
unsigned
long
__xchg
(
unsigned
long
x
,
34
volatile
void
*
ptr
,
35
int
size
)
36
{
37
switch
(size) {
38
case
4:
39
return
xchg_u32(x, ptr);
40
default
:
41
__xchg_called_with_bad_pointer
();
42
return
x
;
43
}
44
}
45
46
static
inline
unsigned
long
__cmpxchg_u32(
volatile
int
*m,
unsigned
long
old,
47
unsigned
long
new
)
48
{
49
__u32
ret
;
50
51
asm
volatile
(
52
"1: ssrf 5\n"
53
" ld.w %[ret], %[m]\n"
54
" cp.w %[ret], %[old]\n"
55
" brne 2f\n"
56
" stcond %[m], %[new]\n"
57
" brne 1b\n"
58
"2:\n"
59
: [
ret
]
"=&r"
(
ret
), [m]
"=m"
(*m)
60
:
"m"
(
m
), [old]
"ir"
(old), [
new
]
"r"
(
new
)
61
:
"memory"
,
"cc"
);
62
return
ret
;
63
}
64
65
extern
unsigned
long
__cmpxchg_u64_unsupported_on_32bit_kernels
(
66
volatile
int
* m,
unsigned
long
old,
unsigned
long
new
);
67
#define __cmpxchg_u64 __cmpxchg_u64_unsupported_on_32bit_kernels
68
69
/* This function doesn't exist, so you'll get a linker error
70
if something tries to do an invalid cmpxchg(). */
71
extern
void
__cmpxchg_called_with_bad_pointer
(
void
);
72
73
#define __HAVE_ARCH_CMPXCHG 1
74
75
static
inline
unsigned
long
__cmpxchg
(
volatile
void
*ptr,
unsigned
long
old,
76
unsigned
long
new
,
int
size)
77
{
78
switch
(size) {
79
case
4:
80
return
__cmpxchg_u32(ptr, old,
new
);
81
case
8:
82
return
__cmpxchg_u64
(ptr, old,
new
);
83
}
84
85
__cmpxchg_called_with_bad_pointer
();
86
return
old;
87
}
88
89
#define cmpxchg(ptr, old, new) \
90
((typeof(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), \
91
(unsigned long)(new), \
92
sizeof(*(ptr))))
93
94
#include <
asm-generic/cmpxchg-local.h
>
95
96
static
inline
unsigned
long
__cmpxchg_local
(
volatile
void
*ptr,
97
unsigned
long
old,
98
unsigned
long
new
,
int
size)
99
{
100
switch
(size) {
101
case
4:
102
return
__cmpxchg_u32(ptr, old,
new
);
103
default
:
104
return
__cmpxchg_local_generic(ptr, old,
new
, size);
105
}
106
107
return
old;
108
}
109
110
#define cmpxchg_local(ptr, old, new) \
111
((typeof(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(old), \
112
(unsigned long)(new), \
113
sizeof(*(ptr))))
114
115
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
116
117
#endif
/* __ASM_AVR32_CMPXCHG_H */
Generated on Thu Jan 10 2013 12:49:17 for Linux Kernel by
1.8.2