Groonga 3.0.9 Source Code Document
Main Page
Related Pages
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Pages
groonga
vendor
nginx-1.4.2
src
os
unix
ngx_gcc_atomic_x86.h
Go to the documentation of this file.
1
2
/*
3
* Copyright (C) Igor Sysoev
4
* Copyright (C) Nginx, Inc.
5
*/
6
7
8
#if (NGX_SMP)
9
#define NGX_SMP_LOCK "lock;"
10
#else
11
#define NGX_SMP_LOCK
12
#endif
13
14
15
/*
16
* "cmpxchgl r, [m]":
17
*
18
* if (eax == [m]) {
19
* zf = 1;
20
* [m] = r;
21
* } else {
22
* zf = 0;
23
* eax = [m];
24
* }
25
*
26
*
27
* The "r" means the general register.
28
* The "=a" and "a" are the %eax register.
29
* Although we can return result in any register, we use "a" because it is
30
* used in cmpxchgl anyway. The result is actually in %al but not in %eax,
31
* however, as the code is inlined gcc can test %al as well as %eax,
32
* and icc adds "movzbl %al, %eax" by itself.
33
*
34
* The "cc" means that flags were changed.
35
*/
36
37
static
ngx_inline
ngx_atomic_uint_t
38
ngx_atomic_cmp_set(
ngx_atomic_t
*lock,
ngx_atomic_uint_t
old,
39
ngx_atomic_uint_t
set
)
40
{
41
u_char res;
42
43
__asm__
volatile
(
44
45
NGX_SMP_LOCK
46
" cmpxchgl %3, %1; "
47
" sete %0; "
48
49
:
"=a"
(res) :
"m"
(*lock),
"a"
(old),
"r"
(
set
) :
"cc"
,
"memory"
);
50
51
return
res;
52
}
53
54
55
/*
56
* "xaddl r, [m]":
57
*
58
* temp = [m];
59
* [m] += r;
60
* r = temp;
61
*
62
*
63
* The "+r" means the general register.
64
* The "cc" means that flags were changed.
65
*/
66
67
68
#if !(( __GNUC__ == 2 && __GNUC_MINOR__ <= 7 ) || ( __INTEL_COMPILER >= 800 ))
69
70
/*
71
* icc 8.1 and 9.0 compile broken code with -march=pentium4 option:
72
* ngx_atomic_fetch_add() always return the input "add" value,
73
* so we use the gcc 2.7 version.
74
*
75
* icc 8.1 and 9.0 with -march=pentiumpro option or icc 7.1 compile
76
* correct code.
77
*/
78
79
static
ngx_inline
ngx_atomic_int_t
80
ngx_atomic_fetch_add(
ngx_atomic_t
*value,
ngx_atomic_int_t
add)
81
{
82
__asm__
volatile
(
83
84
NGX_SMP_LOCK
85
" xaddl %0, %1; "
86
87
:
"+r"
(add) :
"m"
(*value) :
"cc"
,
"memory"
);
88
89
return
add;
90
}
91
92
93
#else
94
95
/*
96
* gcc 2.7 does not support "+r", so we have to use the fixed
97
* %eax ("=a" and "a") and this adds two superfluous instructions in the end
98
* of code, something like this: "mov %eax, %edx / mov %edx, %eax".
99
*/
100
101
static
ngx_inline
ngx_atomic_int_t
102
ngx_atomic_fetch_add(
ngx_atomic_t
*value,
ngx_atomic_int_t
add)
103
{
104
ngx_atomic_uint_t
old;
105
106
__asm__
volatile
(
107
108
NGX_SMP_LOCK
109
" xaddl %2, %1; "
110
111
:
"=a"
(old) :
"m"
(*value),
"a"
(add) :
"cc"
,
"memory"
);
112
113
return
old;
114
}
115
116
#endif
117
118
119
/*
120
* on x86 the write operations go in a program order, so we need only
121
* to disable the gcc reorder optimizations
122
*/
123
124
#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
125
126
/* old "as" does not support "pause" opcode */
127
#define ngx_cpu_pause() __asm__ (".byte 0xf3, 0x90")
Generated on Sun Nov 10 2013 09:49:09 for Groonga 3.0.9 Source Code Document by
1.8.1.2