comparison src/os/unix/ngx_gcc_atomic_x86.h @ 110:dad2fe8ecf08 NGINX_0_3_2

nginx 0.3.2 *) 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 <http://sysoev.ru>
date Wed, 12 Oct 2005 00:00:00 +0400
parents
children 408f195b3482
comparison
equal deleted inserted replaced
109:97da525033a1 110:dad2fe8ecf08
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