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