Mercurial > hg > nginx
comparison src/os/unix/ngx_gcc_atomic_x86.h @ 561:e48ebafc6939 release-0.3.2
nginx-0.3.2-RELEASE import
*) Feature: the Sun Studio 10 C compiler support.
*) Feature: the "proxy_upstream_max_fails",
"proxy_upstream_fail_timeout", "fastcgi_upstream_max_fails", and
"fastcgi_upstream_fail_timeout" directives.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 12 Oct 2005 13:50:36 +0000 |
parents | |
children | 9c2f3ed7a247 |
comparison
equal
deleted
inserted
replaced
560:8886091eddd2 | 561:e48ebafc6939 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #if (NGX_SMP) | |
8 #define NGX_SMP_LOCK "lock;" | |
9 #else | |
10 #define NGX_SMP_LOCK | |
11 #endif | |
12 | |
13 | |
14 /* | |
15 * "cmpxchgl r, [m]": | |
16 * | |
17 * if (eax == [m]) { | |
18 * zf = 1; | |
19 * [m] = r; | |
20 * } else { | |
21 * zf = 0; | |
22 * eax = [m]; | |
23 * } | |
24 * | |
25 * | |
26 * The "q" is any of the %eax, %ebx, %ecx, or %edx registers. | |
27 * The "=a" and "a" are the %eax register. Although we can return result | |
28 * in any register, we use %eax because it is used in cmpxchgl anyway. | |
29 * The "cc" means that flags were changed. | |
30 */ | |
31 | |
32 static ngx_inline ngx_atomic_uint_t | |
33 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, | |
34 ngx_atomic_uint_t set) | |
35 { | |
36 ngx_atomic_uint_t res; | |
37 | |
38 __asm__ volatile ( | |
39 | |
40 NGX_SMP_LOCK | |
41 " cmpxchgl %3, %1; " | |
42 " setz %b0; " | |
43 " movzbl %b0, %0; " | |
44 | |
45 : "=a" (res) : "m" (*lock), "a" (old), "q" (set) : "cc", "memory"); | |
46 | |
47 return res; | |
48 } | |
49 | |
50 | |
51 /* | |
52 * "xaddl r, [m]": | |
53 * | |
54 * temp = [m]; | |
55 * [m] += r; | |
56 * r = temp; | |
57 * | |
58 * | |
59 * The "+q" is any of the %eax, %ebx, %ecx, or %edx registers. | |
60 * The "cc" means that flags were changed. | |
61 */ | |
62 | |
63 | |
64 #if !(__GNUC__ == 2 && __GNUC_MINOR__ <= 7) | |
65 | |
66 static ngx_inline ngx_atomic_int_t | |
67 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) | |
68 { | |
69 __asm__ volatile ( | |
70 | |
71 NGX_SMP_LOCK | |
72 " xaddl %0, %1; " | |
73 | |
74 : "+q" (add) : "m" (*value) : "cc", "memory"); | |
75 | |
76 return add; | |
77 } | |
78 | |
79 | |
80 #else /* (__GNUC__ == 2 && __GNUC_MINOR__ <= 7) */ | |
81 | |
82 /* | |
83 * gcc 2.7 does not support "+q", so we have to use the fixed %eax ("=a" and | |
84 * "a") and this adds two superfluous instructions in the end of code, | |
85 * something like this: "mov %eax, %edx / mov %edx, %eax". | |
86 */ | |
87 | |
88 static ngx_inline ngx_atomic_int_t | |
89 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) | |
90 { | |
91 ngx_atomic_uint_t old; | |
92 | |
93 __asm__ volatile ( | |
94 | |
95 NGX_SMP_LOCK | |
96 " xaddl %2, %1; " | |
97 | |
98 : "=a" (old) : "m" (*value), "a" (add) : "cc", "memory"); | |
99 | |
100 return old; | |
101 } | |
102 | |
103 #endif |