annotate src/os/unix/ngx_gcc_atomic_x86.h @ 4403:c8b9f62cb414

Fixed sched_setaffinity(2) to correctly pass size. Second argument (cpusetsize) is size in bytes, not in bits. Previously used constant 32 resulted in reading of uninitialized memory and caused EINVAL to be returned on some Linux kernels.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 16 Jan 2012 11:13:48 +0000
parents 86897b8c871b
children d620f497c50f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
2 /*
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
4 */
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
5
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
6
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
7 #if (NGX_SMP)
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
8 #define NGX_SMP_LOCK "lock;"
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9 #else
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10 #define NGX_SMP_LOCK
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
11 #endif
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
12
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
13
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
14 /*
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
15 * "cmpxchgl r, [m]":
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
16 *
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
17 * if (eax == [m]) {
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
18 * zf = 1;
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
19 * [m] = r;
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
20 * } else {
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
21 * zf = 0;
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
22 * eax = [m];
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
23 * }
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
24 *
577
4d9ea73a627a nginx-0.3.10-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
25 *
1009
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
26 * The "r" means the general register.
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
27 * The "=a" and "a" are the %eax register.
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
28 * Although we can return result in any register, we use "a" because it is
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
29 * used in cmpxchgl anyway. The result is actually in %al but not in %eax,
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
30 * however, as the code is inlined gcc can test %al as well as %eax,
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
31 * and icc adds "movzbl %al, %eax" by itself.
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
32 *
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
33 * The "cc" means that flags were changed.
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
34 */
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
35
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
36 static ngx_inline ngx_atomic_uint_t
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
37 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
38 ngx_atomic_uint_t set)
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
39 {
1009
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
40 u_char res;
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
41
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
42 __asm__ volatile (
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
43
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
44 NGX_SMP_LOCK
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
45 " cmpxchgl %3, %1; "
1009
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
46 " sete %0; "
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
47
1009
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
48 : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
49
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
50 return res;
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
51 }
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
52
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
53
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
54 /*
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
55 * "xaddl r, [m]":
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
56 *
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
57 * temp = [m];
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
58 * [m] += r;
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
59 * r = temp;
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
60 *
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
61 *
1009
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
62 * The "+r" means the general register.
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
63 * The "cc" means that flags were changed.
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64 */
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
65
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66
589
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
67 #if !(( __GNUC__ == 2 && __GNUC_MINOR__ <= 7 ) || ( __INTEL_COMPILER >= 800 ))
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
68
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
69 /*
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
70 * icc 8.1 and 9.0 compile broken code with -march=pentium4 option:
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
71 * ngx_atomic_fetch_add() always return the input "add" value,
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
72 * so we use the gcc 2.7 version.
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
73 *
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
74 * icc 8.1 and 9.0 with -march=pentiumpro option or icc 7.1 compile
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
75 * correct code.
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
76 */
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
78 static ngx_inline ngx_atomic_int_t
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
79 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
80 {
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
81 __asm__ volatile (
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
82
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
83 NGX_SMP_LOCK
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
84 " xaddl %0, %1; "
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
85
1009
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
86 : "+r" (add) : "m" (*value) : "cc", "memory");
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
87
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88 return add;
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
89 }
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
90
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
91
589
d4e858a5751a nginx-0.3.16-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 577
diff changeset
92 #else
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
93
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
94 /*
1009
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
95 * gcc 2.7 does not support "+r", so we have to use the fixed
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
96 * %eax ("=a" and "a") and this adds two superfluous instructions in the end
ee5f21acea76 optimization
Igor Sysoev <igor@sysoev.ru>
parents: 611
diff changeset
97 * of code, something like this: "mov %eax, %edx / mov %edx, %eax".
561
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
98 */
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
99
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
100 static ngx_inline ngx_atomic_int_t
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
101 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
102 {
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
103 ngx_atomic_uint_t old;
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
104
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
105 __asm__ volatile (
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
106
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
107 NGX_SMP_LOCK
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
108 " xaddl %2, %1; "
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
109
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
110 : "=a" (old) : "m" (*value), "a" (add) : "cc", "memory");
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
111
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
112 return old;
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
113 }
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
114
e48ebafc6939 nginx-0.3.2-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
115 #endif
563
9c2f3ed7a247 nginx-0.3.3-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 561
diff changeset
116
9c2f3ed7a247 nginx-0.3.3-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 561
diff changeset
117
9c2f3ed7a247 nginx-0.3.3-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 561
diff changeset
118 /*
9c2f3ed7a247 nginx-0.3.3-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 561
diff changeset
119 * on x86 the write operations go in a program order, so we need only
9c2f3ed7a247 nginx-0.3.3-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 561
diff changeset
120 * to disable the gcc reorder optimizations
9c2f3ed7a247 nginx-0.3.3-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 561
diff changeset
121 */
9c2f3ed7a247 nginx-0.3.3-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 561
diff changeset
122
9c2f3ed7a247 nginx-0.3.3-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 561
diff changeset
123 #define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
611
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 589
diff changeset
124
3364
86897b8c871b fix comment
Igor Sysoev <igor@sysoev.ru>
parents: 1009
diff changeset
125 /* old "as" does not support "pause" opcode */
611
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 589
diff changeset
126 #define ngx_cpu_pause() __asm__ (".byte 0xf3, 0x90")