Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #ifndef _NGX_ATOMIC_H_INCLUDED_
0009 #define _NGX_ATOMIC_H_INCLUDED_
0010 
0011 
0012 #include <ngx_config.h>
0013 #include <ngx_core.h>
0014 
0015 
0016 #if (NGX_HAVE_LIBATOMIC)
0017 
0018 #define AO_REQUIRE_CAS
0019 #include <atomic_ops.h>
0020 
0021 #define NGX_HAVE_ATOMIC_OPS  1
0022 
0023 typedef long                        ngx_atomic_int_t;
0024 typedef AO_t                        ngx_atomic_uint_t;
0025 typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
0026 
0027 #if (NGX_PTR_SIZE == 8)
0028 #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)
0029 #else
0030 #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
0031 #endif
0032 
0033 #define ngx_atomic_cmp_set(lock, old, new)                                    \
0034     AO_compare_and_swap(lock, old, new)
0035 #define ngx_atomic_fetch_add(value, add)                                      \
0036     AO_fetch_and_add(value, add)
0037 #define ngx_memory_barrier()        AO_nop()
0038 #define ngx_cpu_pause()
0039 
0040 
0041 #elif (NGX_DARWIN_ATOMIC)
0042 
0043 /*
0044  * use Darwin 8 atomic(3) and barrier(3) operations
0045  * optimized at run-time for UP and SMP
0046  */
0047 
0048 #include <libkern/OSAtomic.h>
0049 
0050 /* "bool" conflicts with perl's CORE/handy.h */
0051 #if 0
0052 #undef bool
0053 #endif
0054 
0055 
0056 #define NGX_HAVE_ATOMIC_OPS  1
0057 
0058 #if (NGX_PTR_SIZE == 8)
0059 
0060 typedef int64_t                     ngx_atomic_int_t;
0061 typedef uint64_t                    ngx_atomic_uint_t;
0062 #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)
0063 
0064 #define ngx_atomic_cmp_set(lock, old, new)                                    \
0065     OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)
0066 
0067 #define ngx_atomic_fetch_add(value, add)                                      \
0068     (OSAtomicAdd64(add, (int64_t *) value) - add)
0069 
0070 #else
0071 
0072 typedef int32_t                     ngx_atomic_int_t;
0073 typedef uint32_t                    ngx_atomic_uint_t;
0074 #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
0075 
0076 #define ngx_atomic_cmp_set(lock, old, new)                                    \
0077     OSAtomicCompareAndSwap32Barrier(old, new, (int32_t *) lock)
0078 
0079 #define ngx_atomic_fetch_add(value, add)                                      \
0080     (OSAtomicAdd32(add, (int32_t *) value) - add)
0081 
0082 #endif
0083 
0084 #define ngx_memory_barrier()        OSMemoryBarrier()
0085 
0086 #define ngx_cpu_pause()
0087 
0088 typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
0089 
0090 
0091 #elif (NGX_HAVE_GCC_ATOMIC)
0092 
0093 /* GCC 4.1 builtin atomic operations */
0094 
0095 #define NGX_HAVE_ATOMIC_OPS  1
0096 
0097 typedef long                        ngx_atomic_int_t;
0098 typedef unsigned long               ngx_atomic_uint_t;
0099 
0100 #if (NGX_PTR_SIZE == 8)
0101 #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)
0102 #else
0103 #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
0104 #endif
0105 
0106 typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
0107 
0108 
0109 #define ngx_atomic_cmp_set(lock, old, set)                                    \
0110     __sync_bool_compare_and_swap(lock, old, set)
0111 
0112 #define ngx_atomic_fetch_add(value, add)                                      \
0113     __sync_fetch_and_add(value, add)
0114 
0115 #define ngx_memory_barrier()        __sync_synchronize()
0116 
0117 #if ( __i386__ || __i386 || __amd64__ || __amd64 )
0118 #define ngx_cpu_pause()             __asm__ ("pause")
0119 #else
0120 #define ngx_cpu_pause()
0121 #endif
0122 
0123 
0124 #elif ( __i386__ || __i386 )
0125 
0126 typedef int32_t                     ngx_atomic_int_t;
0127 typedef uint32_t                    ngx_atomic_uint_t;
0128 typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
0129 #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
0130 
0131 
0132 #if ( __SUNPRO_C )
0133 
0134 #define NGX_HAVE_ATOMIC_OPS  1
0135 
0136 ngx_atomic_uint_t
0137 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
0138     ngx_atomic_uint_t set);
0139 
0140 ngx_atomic_int_t
0141 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
0142 
0143 /*
0144  * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
0145  * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_x86.il
0146  */
0147 
0148 void
0149 ngx_cpu_pause(void);
0150 
0151 /* the code in src/os/unix/ngx_sunpro_x86.il */
0152 
0153 #define ngx_memory_barrier()        __asm (".volatile"); __asm (".nonvolatile")
0154 
0155 
0156 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
0157 
0158 #define NGX_HAVE_ATOMIC_OPS  1
0159 
0160 #include "ngx_gcc_atomic_x86.h"
0161 
0162 #endif
0163 
0164 
0165 #elif ( __amd64__ || __amd64 )
0166 
0167 typedef int64_t                     ngx_atomic_int_t;
0168 typedef uint64_t                    ngx_atomic_uint_t;
0169 typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
0170 #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)
0171 
0172 
0173 #if ( __SUNPRO_C )
0174 
0175 #define NGX_HAVE_ATOMIC_OPS  1
0176 
0177 ngx_atomic_uint_t
0178 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
0179     ngx_atomic_uint_t set);
0180 
0181 ngx_atomic_int_t
0182 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
0183 
0184 /*
0185  * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
0186  * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_amd64.il
0187  */
0188 
0189 void
0190 ngx_cpu_pause(void);
0191 
0192 /* the code in src/os/unix/ngx_sunpro_amd64.il */
0193 
0194 #define ngx_memory_barrier()        __asm (".volatile"); __asm (".nonvolatile")
0195 
0196 
0197 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
0198 
0199 #define NGX_HAVE_ATOMIC_OPS  1
0200 
0201 #include "ngx_gcc_atomic_amd64.h"
0202 
0203 #endif
0204 
0205 
0206 #elif ( __sparc__ || __sparc || __sparcv9 )
0207 
0208 #if (NGX_PTR_SIZE == 8)
0209 
0210 typedef int64_t                     ngx_atomic_int_t;
0211 typedef uint64_t                    ngx_atomic_uint_t;
0212 #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)
0213 
0214 #else
0215 
0216 typedef int32_t                     ngx_atomic_int_t;
0217 typedef uint32_t                    ngx_atomic_uint_t;
0218 #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
0219 
0220 #endif
0221 
0222 typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
0223 
0224 
0225 #if ( __SUNPRO_C )
0226 
0227 #define NGX_HAVE_ATOMIC_OPS  1
0228 
0229 #include "ngx_sunpro_atomic_sparc64.h"
0230 
0231 
0232 #else /* ( __GNUC__ || __INTEL_COMPILER ) */
0233 
0234 #define NGX_HAVE_ATOMIC_OPS  1
0235 
0236 #include "ngx_gcc_atomic_sparc64.h"
0237 
0238 #endif
0239 
0240 
0241 #elif ( __powerpc__ || __POWERPC__ )
0242 
0243 #define NGX_HAVE_ATOMIC_OPS  1
0244 
0245 #if (NGX_PTR_SIZE == 8)
0246 
0247 typedef int64_t                     ngx_atomic_int_t;
0248 typedef uint64_t                    ngx_atomic_uint_t;
0249 #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)
0250 
0251 #else
0252 
0253 typedef int32_t                     ngx_atomic_int_t;
0254 typedef uint32_t                    ngx_atomic_uint_t;
0255 #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
0256 
0257 #endif
0258 
0259 typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
0260 
0261 
0262 #include "ngx_gcc_atomic_ppc.h"
0263 
0264 #endif
0265 
0266 
0267 #if !(NGX_HAVE_ATOMIC_OPS)
0268 
0269 #define NGX_HAVE_ATOMIC_OPS  0
0270 
0271 typedef int32_t                     ngx_atomic_int_t;
0272 typedef uint32_t                    ngx_atomic_uint_t;
0273 typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
0274 #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
0275 
0276 
0277 static ngx_inline ngx_atomic_uint_t
0278 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
0279     ngx_atomic_uint_t set)
0280 {
0281     if (*lock == old) {
0282         *lock = set;
0283         return 1;
0284     }
0285 
0286     return 0;
0287 }
0288 
0289 
0290 static ngx_inline ngx_atomic_int_t
0291 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
0292 {
0293     ngx_atomic_int_t  old;
0294 
0295     old = *value;
0296     *value += add;
0297 
0298     return old;
0299 }
0300 
0301 #define ngx_memory_barrier()
0302 #define ngx_cpu_pause()
0303 
0304 #endif
0305 
0306 
0307 void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);
0308 
0309 #define ngx_trylock(lock)  (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
0310 #define ngx_unlock(lock)    *(lock) = 0
0311 
0312 
0313 #endif /* _NGX_ATOMIC_H_INCLUDED_ */