Mercurial > hg > nginx-vendor-0-8
comparison src/os/unix/ngx_atomic.h @ 0:f0b350454894 NGINX_0_1_0
nginx 0.1.0
*) The first public version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Oct 2004 00:00:00 +0400 |
parents | |
children | 41ccba1aba45 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0b350454894 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #ifndef _NGX_ATOMIC_H_INCLUDED_ | |
8 #define _NGX_ATOMIC_H_INCLUDED_ | |
9 | |
10 | |
11 #include <ngx_config.h> | |
12 #include <ngx_core.h> | |
13 | |
14 | |
15 #if ( __i386__ || __amd64__ ) | |
16 | |
17 #define NGX_HAVE_ATOMIC_OPS 1 | |
18 | |
19 typedef volatile uint32_t ngx_atomic_t; | |
20 | |
21 #if (NGX_SMP) | |
22 #define NGX_SMP_LOCK "lock;" | |
23 #else | |
24 #define NGX_SMP_LOCK | |
25 #endif | |
26 | |
27 | |
28 static ngx_inline uint32_t ngx_atomic_inc(ngx_atomic_t *value) | |
29 { | |
30 uint32_t old; | |
31 | |
32 __asm__ volatile ( | |
33 | |
34 NGX_SMP_LOCK | |
35 " xaddl %0, %2; " | |
36 " incl %0; " | |
37 | |
38 : "=q" (old) : "0" (1), "m" (*value)); | |
39 | |
40 return old; | |
41 } | |
42 | |
43 | |
44 #if 0 | |
45 | |
46 static ngx_inline uint32_t ngx_atomic_dec(ngx_atomic_t *value) | |
47 { | |
48 uint32_t old; | |
49 | |
50 __asm__ volatile ( | |
51 | |
52 NGX_SMP_LOCK | |
53 " xaddl %0, %1; " | |
54 " decl %0; " | |
55 | |
56 : "=q" (old) : "0" (-1), "m" (*value)); | |
57 | |
58 return old; | |
59 } | |
60 | |
61 #endif | |
62 | |
63 | |
64 static ngx_inline uint32_t ngx_atomic_cmp_set(ngx_atomic_t *lock, | |
65 ngx_atomic_t old, | |
66 ngx_atomic_t set) | |
67 { | |
68 uint32_t res; | |
69 | |
70 __asm__ volatile ( | |
71 | |
72 NGX_SMP_LOCK | |
73 " cmpxchgl %3, %1; " | |
74 " setz %%al; " | |
75 " movzbl %%al, %0; " | |
76 | |
77 : "=a" (res) : "m" (*lock), "a" (old), "q" (set)); | |
78 | |
79 return res; | |
80 } | |
81 | |
82 | |
83 #elif ( __sparc__ ) | |
84 | |
85 #define NGX_HAVE_ATOMIC_OPS 1 | |
86 | |
87 typedef volatile uint32_t ngx_atomic_t; | |
88 | |
89 | |
90 static ngx_inline uint32_t ngx_atomic_inc(ngx_atomic_t *value) | |
91 { | |
92 uint32_t old, new, res; | |
93 | |
94 old = *value; | |
95 | |
96 for ( ;; ) { | |
97 | |
98 new = old + 1; | |
99 res = new; | |
100 | |
101 __asm__ volatile ( | |
102 | |
103 "casa [%1] 0x80, %2, %0" | |
104 | |
105 : "+r" (res) : "r" (value), "r" (old)); | |
106 | |
107 if (res == old) { | |
108 return new; | |
109 } | |
110 | |
111 old = res; | |
112 } | |
113 } | |
114 | |
115 | |
116 static ngx_inline uint32_t ngx_atomic_cmp_set(ngx_atomic_t *lock, | |
117 ngx_atomic_t old, | |
118 ngx_atomic_t set) | |
119 { | |
120 uint32_t res = (uint32_t) set; | |
121 | |
122 __asm__ volatile ( | |
123 | |
124 "casa [%1] 0x80, %2, %0" | |
125 | |
126 : "+r" (res) : "r" (lock), "r" (old)); | |
127 | |
128 return (res == old); | |
129 } | |
130 | |
131 #else | |
132 | |
133 #define NGX_HAVE_ATOMIC_OPS 0 | |
134 | |
135 typedef volatile uint32_t ngx_atomic_t; | |
136 | |
137 #define ngx_atomic_inc(x) ++(*(x)); | |
138 | |
139 static ngx_inline uint32_t ngx_atomic_cmp_set(ngx_atomic_t *lock, | |
140 ngx_atomic_t old, | |
141 ngx_atomic_t set) | |
142 { | |
143 return 1; | |
144 } | |
145 | |
146 #endif | |
147 | |
148 | |
149 void ngx_spinlock(ngx_atomic_t *lock, ngx_uint_t spin); | |
150 | |
151 #define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1)) | |
152 #define ngx_unlock(lock) *(lock) = 0 | |
153 | |
154 | |
155 #endif /* _NGX_ATOMIC_H_INCLUDED_ */ |