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
parisc
include
asm
cmpxchg.h
Go to the documentation of this file.
1
/*
2
* forked from parisc asm/atomic.h which was:
3
* Copyright (C) 2000 Philipp Rumpf <
[email protected]
>
4
* Copyright (C) 2006 Kyle McMartin <
[email protected]
>
5
*/
6
7
#ifndef _ASM_PARISC_CMPXCHG_H_
8
#define _ASM_PARISC_CMPXCHG_H_
9
10
/* This should get optimized out since it's never called.
11
** Or get a link error if xchg is used "wrong".
12
*/
13
extern
void
__xchg_called_with_bad_pointer
(
void
);
14
15
/* __xchg32/64 defined in arch/parisc/lib/bitops.c */
16
extern
unsigned
long
__xchg8
(
char
,
char
*);
17
extern
unsigned
long
__xchg32
(
int
,
int
*);
18
#ifdef CONFIG_64BIT
19
extern
unsigned
long
__xchg64(
unsigned
long
,
unsigned
long
*);
20
#endif
21
22
/* optimizer better get rid of switch since size is a constant */
23
static
inline
unsigned
long
24
__xchg
(
unsigned
long
x
, __volatile__
void
*
ptr
,
int
size
)
25
{
26
switch
(size) {
27
#ifdef CONFIG_64BIT
28
case
8:
return
__xchg64(x, (
unsigned
long
*) ptr);
29
#endif
30
case
4:
return
__xchg32
((
int
) x, (
int
*) ptr);
31
case
1:
return
__xchg8
((
char
) x, (
char
*) ptr);
32
}
33
__xchg_called_with_bad_pointer
();
34
return
x
;
35
}
36
37
/*
38
** REVISIT - Abandoned use of LDCW in xchg() for now:
39
** o need to test sizeof(*ptr) to avoid clearing adjacent bytes
40
** o and while we are at it, could CONFIG_64BIT code use LDCD too?
41
**
42
** if (__builtin_constant_p(x) && (x == NULL))
43
** if (((unsigned long)p & 0xf) == 0)
44
** return __ldcw(p);
45
*/
46
#define xchg(ptr, x) \
47
((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
48
49
#define __HAVE_ARCH_CMPXCHG 1
50
51
/* bug catcher for when unsupported size is used - won't link */
52
extern
void
__cmpxchg_called_with_bad_pointer
(
void
);
53
54
/* __cmpxchg_u32/u64 defined in arch/parisc/lib/bitops.c */
55
extern
unsigned
long
__cmpxchg_u32
(
volatile
unsigned
int
*
m
,
unsigned
int
old,
56
unsigned
int
new_);
57
extern
unsigned
long
__cmpxchg_u64
(
volatile
unsigned
long
*ptr,
58
unsigned
long
old,
unsigned
long
new_);
59
60
/* don't worry...optimizer will get rid of most of this */
61
static
inline
unsigned
long
62
__cmpxchg
(
volatile
void
*ptr,
unsigned
long
old,
unsigned
long
new_,
int
size)
63
{
64
switch
(size) {
65
#ifdef CONFIG_64BIT
66
case
8:
return
__cmpxchg_u64
((
unsigned
long
*)ptr, old, new_);
67
#endif
68
case
4:
return
__cmpxchg_u32
((
unsigned
int
*)ptr,
69
(
unsigned
int
)old, (
unsigned
int
)new_);
70
}
71
__cmpxchg_called_with_bad_pointer
();
72
return
old;
73
}
74
75
#define cmpxchg(ptr, o, n) \
76
({ \
77
__typeof__(*(ptr)) _o_ = (o); \
78
__typeof__(*(ptr)) _n_ = (n); \
79
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
80
(unsigned long)_n_, sizeof(*(ptr))); \
81
})
82
83
#include <
asm-generic/cmpxchg-local.h
>
84
85
static
inline
unsigned
long
__cmpxchg_local
(
volatile
void
*ptr,
86
unsigned
long
old,
87
unsigned
long
new_,
int
size)
88
{
89
switch
(size) {
90
#ifdef CONFIG_64BIT
91
case
8:
return
__cmpxchg_u64
((
unsigned
long
*)ptr, old, new_);
92
#endif
93
case
4:
return
__cmpxchg_u32
(ptr, old, new_);
94
default
:
95
return
__cmpxchg_local_generic(ptr, old, new_, size);
96
}
97
}
98
99
/*
100
* cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
101
* them available.
102
*/
103
#define cmpxchg_local(ptr, o, n) \
104
((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
105
(unsigned long)(n), sizeof(*(ptr))))
106
#ifdef CONFIG_64BIT
107
#define cmpxchg64_local(ptr, o, n) \
108
({ \
109
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
110
cmpxchg_local((ptr), (o), (n)); \
111
})
112
#else
113
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
114
#endif
115
116
#endif
/* _ASM_PARISC_CMPXCHG_H_ */
Generated on Thu Jan 10 2013 12:49:17 for Linux Kernel by
1.8.2