1
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
5 */
6
7
8 /*
9 * "casa [r1] 0x80, r2, r0" and
10 * "casxa [r1] 0x80, r2, r0" do the following:
11 *
12 * if ([r1] == r2) {
13 * swap(r0, [r1]);
14 * } else {
15 * r0 = [r1];
16 * }
17 *
18 * so "r0 == r2" means that the operation was successful.
19 *
20 *
21 * The "r" means the general register.
22 * The "+r" means the general register used for both input and output.
23 */
24
25
26 #if (NGX_PTR_SIZE == 4)
27 #define NGX_CASA "casa"
28 #else
29 #define NGX_CASA "casxa"
30 #endif
31
32
33 static ngx_inline ngx_atomic_uint_t
ngx_atomic_cmp_set(ngx_atomic_t * lock,ngx_atomic_uint_t old,ngx_atomic_uint_t set)34 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
35 ngx_atomic_uint_t set)
36 {
37 __asm__ volatile (
38
39 NGX_CASA " [%1] 0x80, %2, %0"
40
41 : "+r" (set) : "r" (lock), "r" (old) : "memory");
42
43 return (set == old);
44 }
45
46
47 static ngx_inline ngx_atomic_int_t
ngx_atomic_fetch_add(ngx_atomic_t * value,ngx_atomic_int_t add)48 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
49 {
50 ngx_atomic_uint_t old, res;
51
52 old = *value;
53
54 for ( ;; ) {
55
56 res = old + add;
57
58 __asm__ volatile (
59
60 NGX_CASA " [%1] 0x80, %2, %0"
61
62 : "+r" (res) : "r" (value), "r" (old) : "memory");
63
64 if (res == old) {
65 return res;
66 }
67
68 old = res;
69 }
70 }
71
72
73 #if (NGX_SMP)
74 #define ngx_memory_barrier() \
75 __asm__ volatile ( \
76 "membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad" \
77 ::: "memory")
78 #else
79 #define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
80 #endif
81
82 #define ngx_cpu_pause()
83