annotate src/os/unix/ngx_gcc_atomic_x86.h @ 391:1d9bef53cd8e

Range filter: late_ranges functionality. Add one more filtering point after postpone filter. This allows to serve range capable replies with subrequests. It's not as efficient as range filtering for static data (i.e. doesn't save us from reading data from disk if some filter needs them in memory), but it may save some network bandwidth for us and for our users.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 21 Jul 2008 05:33:01 +0400
parents 052a7b1d40e5
children 5c576ea5dbd9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
1
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
2 /*
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
4 */
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
5
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
6
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
7 #if (NGX_SMP)
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
8 #define NGX_SMP_LOCK "lock;"
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
9 #else
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
10 #define NGX_SMP_LOCK
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
11 #endif
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
12
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
13
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
14 /*
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
15 * "cmpxchgl r, [m]":
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
16 *
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
17 * if (eax == [m]) {
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
18 * zf = 1;
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
19 * [m] = r;
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
20 * } else {
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
21 * zf = 0;
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
22 * eax = [m];
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
23 * }
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
24 *
126
df17fbafec8f nginx 0.3.10
Igor Sysoev <http://sysoev.ru>
parents: 112
diff changeset
25 *
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
26 * The "r" means the general register.
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
27 * The "=a" and "a" are the %eax register.
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
28 * Although we can return result in any register, we use "a" because it is
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
29 * used in cmpxchgl anyway. The result is actually in %al but not in %eax,
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
30 * however, as the code is inlined gcc can test %al as well as %eax,
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
31 * and icc adds "movzbl %al, %eax" by itself.
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
32 *
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
33 * The "cc" means that flags were changed.
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
34 */
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
35
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
36 static ngx_inline ngx_atomic_uint_t
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
37 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
38 ngx_atomic_uint_t set)
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
39 {
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
40 u_char res;
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
41
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
42 __asm__ volatile (
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
43
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
44 NGX_SMP_LOCK
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
45 " cmpxchgl %3, %1; "
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
46 " sete %0; "
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
47
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
48 : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
49
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
50 return res;
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
51 }
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
52
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
53
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
54 /*
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
55 * "xaddl r, [m]":
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
56 *
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
57 * temp = [m];
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
58 * [m] += r;
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
59 * r = temp;
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
60 *
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
61 *
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
62 * The "+r" means the general register.
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
63 * The "cc" means that flags were changed.
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
64 */
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
65
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
66
138
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
67 #if !(( __GNUC__ == 2 && __GNUC_MINOR__ <= 7 ) || ( __INTEL_COMPILER >= 800 ))
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
68
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
69 /*
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
70 * icc 8.1 and 9.0 compile broken code with -march=pentium4 option:
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
71 * ngx_atomic_fetch_add() always return the input "add" value,
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
72 * so we use the gcc 2.7 version.
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
73 *
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
74 * icc 8.1 and 9.0 with -march=pentiumpro option or icc 7.1 compile
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
75 * correct code.
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
76 */
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
77
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
78 static ngx_inline ngx_atomic_int_t
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
79 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
80 {
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
81 __asm__ volatile (
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
82
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
83 NGX_SMP_LOCK
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
84 " xaddl %0, %1; "
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
85
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
86 : "+r" (add) : "m" (*value) : "cc", "memory");
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
87
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
88 return add;
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
89 }
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
90
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
91
138
8e6d4d96ec4c nginx 0.3.16
Igor Sysoev <http://sysoev.ru>
parents: 126
diff changeset
92 #else
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
93
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
94 /*
274
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
95 * gcc 2.7 does not support "+r", so we have to use the fixed
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
96 * %eax ("=a" and "a") and this adds two superfluous instructions in the end
052a7b1d40e5 nginx 0.5.7
Igor Sysoev <http://sysoev.ru>
parents: 160
diff changeset
97 * of code, something like this: "mov %eax, %edx / mov %edx, %eax".
110
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
98 */
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
99
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
100 static ngx_inline ngx_atomic_int_t
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
101 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
102 {
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
103 ngx_atomic_uint_t old;
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
104
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
105 __asm__ volatile (
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
106
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
107 NGX_SMP_LOCK
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
108 " xaddl %2, %1; "
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
109
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
110 : "=a" (old) : "m" (*value), "a" (add) : "cc", "memory");
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
111
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
112 return old;
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
113 }
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
114
dad2fe8ecf08 nginx 0.3.2
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
115 #endif
112
408f195b3482 nginx 0.3.3
Igor Sysoev <http://sysoev.ru>
parents: 110
diff changeset
116
408f195b3482 nginx 0.3.3
Igor Sysoev <http://sysoev.ru>
parents: 110
diff changeset
117
408f195b3482 nginx 0.3.3
Igor Sysoev <http://sysoev.ru>
parents: 110
diff changeset
118 /*
408f195b3482 nginx 0.3.3
Igor Sysoev <http://sysoev.ru>
parents: 110
diff changeset
119 * on x86 the write operations go in a program order, so we need only
408f195b3482 nginx 0.3.3
Igor Sysoev <http://sysoev.ru>
parents: 110
diff changeset
120 * to disable the gcc reorder optimizations
408f195b3482 nginx 0.3.3
Igor Sysoev <http://sysoev.ru>
parents: 110
diff changeset
121 */
408f195b3482 nginx 0.3.3
Igor Sysoev <http://sysoev.ru>
parents: 110
diff changeset
122
408f195b3482 nginx 0.3.3
Igor Sysoev <http://sysoev.ru>
parents: 110
diff changeset
123 #define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
160
73e8476f9142 nginx 0.3.27
Igor Sysoev <http://sysoev.ru>
parents: 138
diff changeset
124
73e8476f9142 nginx 0.3.27
Igor Sysoev <http://sysoev.ru>
parents: 138
diff changeset
125 /* old as does not support "pause" opcode */
73e8476f9142 nginx 0.3.27
Igor Sysoev <http://sysoev.ru>
parents: 138
diff changeset
126 #define ngx_cpu_pause() __asm__ (".byte 0xf3, 0x90")