blob: e5a6254ec74610639f2648d5dfa006726bf1686b [file] [log] [blame]
Igor Sysoev78452232005-10-12 13:50:36 +00001
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
32static ngx_inline ngx_atomic_uint_t
33ngx_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);
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +000043}
Igor Sysoev78452232005-10-12 13:50:36 +000044
45
46static ngx_inline ngx_atomic_int_t
47ngx_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}
Igor Sysoevc2068d02005-10-19 12:33:58 +000070
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
Igor Sysoevffe71442006-02-08 15:33:12 +000080
81#define ngx_cpu_pause()