Annotation of embedaddon/nginx/src/os/unix/ngx_gcc_atomic_amd64.h, revision 1.1.1.1
1.1 misho 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: * "cmpxchgq r, [m]":
17: *
18: * if (rax == [m]) {
19: * zf = 1;
20: * [m] = r;
21: * } else {
22: * zf = 0;
23: * rax = [m];
24: * }
25: *
26: *
27: * The "r" is any register, %rax (%r0) - %r16.
28: * The "=a" and "a" are the %rax register.
29: * Although we can return result in any register, we use "a" because it is
30: * used in cmpxchgq anyway. The result is actually in %al but not in $rax,
31: * however as the code is inlined gcc can test %al as well as %rax.
32: *
33: * The "cc" means that flags were changed.
34: */
35:
36: static ngx_inline ngx_atomic_uint_t
37: ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
38: ngx_atomic_uint_t set)
39: {
40: u_char res;
41:
42: __asm__ volatile (
43:
44: NGX_SMP_LOCK
45: " cmpxchgq %3, %1; "
46: " sete %0; "
47:
48: : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
49:
50: return res;
51: }
52:
53:
54: /*
55: * "xaddq r, [m]":
56: *
57: * temp = [m];
58: * [m] += r;
59: * r = temp;
60: *
61: *
62: * The "+r" is any register, %rax (%r0) - %r16.
63: * The "cc" means that flags were changed.
64: */
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: " xaddq %0, %1; "
73:
74: : "+r" (add) : "m" (*value) : "cc", "memory");
75:
76: return add;
77: }
78:
79:
80: #define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
81:
82: #define ngx_cpu_pause() __asm__ ("pause")
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>