Annotation of embedaddon/nginx/src/os/unix/ngx_atomic.h, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * Copyright (C) Igor Sysoev
! 4: * Copyright (C) Nginx, Inc.
! 5: */
! 6:
! 7:
! 8: #ifndef _NGX_ATOMIC_H_INCLUDED_
! 9: #define _NGX_ATOMIC_H_INCLUDED_
! 10:
! 11:
! 12: #include <ngx_config.h>
! 13: #include <ngx_core.h>
! 14:
! 15:
! 16: #if (NGX_HAVE_LIBATOMIC)
! 17:
! 18: #define AO_REQUIRE_CAS
! 19: #include <atomic_ops.h>
! 20:
! 21: #define NGX_HAVE_ATOMIC_OPS 1
! 22:
! 23: typedef long ngx_atomic_int_t;
! 24: typedef AO_t ngx_atomic_uint_t;
! 25: typedef volatile ngx_atomic_uint_t ngx_atomic_t;
! 26:
! 27: #if (NGX_PTR_SIZE == 8)
! 28: #define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
! 29: #else
! 30: #define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
! 31: #endif
! 32:
! 33: #define ngx_atomic_cmp_set(lock, old, new) \
! 34: AO_compare_and_swap(lock, old, new)
! 35: #define ngx_atomic_fetch_add(value, add) \
! 36: AO_fetch_and_add(value, add)
! 37: #define ngx_memory_barrier() AO_nop()
! 38: #define ngx_cpu_pause()
! 39:
! 40:
! 41: #elif (NGX_DARWIN_ATOMIC)
! 42:
! 43: /*
! 44: * use Darwin 8 atomic(3) and barrier(3) operations
! 45: * optimized at run-time for UP and SMP
! 46: */
! 47:
! 48: #include <libkern/OSAtomic.h>
! 49:
! 50: /* "bool" conflicts with perl's CORE/handy.h */
! 51: #if 0
! 52: #undef bool
! 53: #endif
! 54:
! 55:
! 56: #define NGX_HAVE_ATOMIC_OPS 1
! 57:
! 58: #if (NGX_PTR_SIZE == 8)
! 59:
! 60: typedef int64_t ngx_atomic_int_t;
! 61: typedef uint64_t ngx_atomic_uint_t;
! 62: #define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
! 63:
! 64: #define ngx_atomic_cmp_set(lock, old, new) \
! 65: OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)
! 66:
! 67: #define ngx_atomic_fetch_add(value, add) \
! 68: (OSAtomicAdd64(add, (int64_t *) value) - add)
! 69:
! 70: #else
! 71:
! 72: typedef int32_t ngx_atomic_int_t;
! 73: typedef uint32_t ngx_atomic_uint_t;
! 74: #define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
! 75:
! 76: #define ngx_atomic_cmp_set(lock, old, new) \
! 77: OSAtomicCompareAndSwap32Barrier(old, new, (int32_t *) lock)
! 78:
! 79: #define ngx_atomic_fetch_add(value, add) \
! 80: (OSAtomicAdd32(add, (int32_t *) value) - add)
! 81:
! 82: #endif
! 83:
! 84: #define ngx_memory_barrier() OSMemoryBarrier()
! 85:
! 86: #define ngx_cpu_pause()
! 87:
! 88: typedef volatile ngx_atomic_uint_t ngx_atomic_t;
! 89:
! 90:
! 91: #elif (NGX_HAVE_GCC_ATOMIC)
! 92:
! 93: /* GCC 4.1 builtin atomic operations */
! 94:
! 95: #define NGX_HAVE_ATOMIC_OPS 1
! 96:
! 97: typedef long ngx_atomic_int_t;
! 98: typedef unsigned long ngx_atomic_uint_t;
! 99:
! 100: #if (NGX_PTR_SIZE == 8)
! 101: #define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
! 102: #else
! 103: #define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
! 104: #endif
! 105:
! 106: typedef volatile ngx_atomic_uint_t ngx_atomic_t;
! 107:
! 108:
! 109: #define ngx_atomic_cmp_set(lock, old, set) \
! 110: __sync_bool_compare_and_swap(lock, old, set)
! 111:
! 112: #define ngx_atomic_fetch_add(value, add) \
! 113: __sync_fetch_and_add(value, add)
! 114:
! 115: #define ngx_memory_barrier() __sync_synchronize()
! 116:
! 117: #if ( __i386__ || __i386 || __amd64__ || __amd64 )
! 118: #define ngx_cpu_pause() __asm__ ("pause")
! 119: #else
! 120: #define ngx_cpu_pause()
! 121: #endif
! 122:
! 123:
! 124: #elif ( __i386__ || __i386 )
! 125:
! 126: typedef int32_t ngx_atomic_int_t;
! 127: typedef uint32_t ngx_atomic_uint_t;
! 128: typedef volatile ngx_atomic_uint_t ngx_atomic_t;
! 129: #define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
! 130:
! 131:
! 132: #if ( __SUNPRO_C )
! 133:
! 134: #define NGX_HAVE_ATOMIC_OPS 1
! 135:
! 136: ngx_atomic_uint_t
! 137: ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
! 138: ngx_atomic_uint_t set);
! 139:
! 140: ngx_atomic_int_t
! 141: ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
! 142:
! 143: /*
! 144: * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
! 145: * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_x86.il
! 146: */
! 147:
! 148: void
! 149: ngx_cpu_pause(void);
! 150:
! 151: /* the code in src/os/unix/ngx_sunpro_x86.il */
! 152:
! 153: #define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
! 154:
! 155:
! 156: #else /* ( __GNUC__ || __INTEL_COMPILER ) */
! 157:
! 158: #define NGX_HAVE_ATOMIC_OPS 1
! 159:
! 160: #include "ngx_gcc_atomic_x86.h"
! 161:
! 162: #endif
! 163:
! 164:
! 165: #elif ( __amd64__ || __amd64 )
! 166:
! 167: typedef int64_t ngx_atomic_int_t;
! 168: typedef uint64_t ngx_atomic_uint_t;
! 169: typedef volatile ngx_atomic_uint_t ngx_atomic_t;
! 170: #define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
! 171:
! 172:
! 173: #if ( __SUNPRO_C )
! 174:
! 175: #define NGX_HAVE_ATOMIC_OPS 1
! 176:
! 177: ngx_atomic_uint_t
! 178: ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
! 179: ngx_atomic_uint_t set);
! 180:
! 181: ngx_atomic_int_t
! 182: ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
! 183:
! 184: /*
! 185: * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
! 186: * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_amd64.il
! 187: */
! 188:
! 189: void
! 190: ngx_cpu_pause(void);
! 191:
! 192: /* the code in src/os/unix/ngx_sunpro_amd64.il */
! 193:
! 194: #define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
! 195:
! 196:
! 197: #else /* ( __GNUC__ || __INTEL_COMPILER ) */
! 198:
! 199: #define NGX_HAVE_ATOMIC_OPS 1
! 200:
! 201: #include "ngx_gcc_atomic_amd64.h"
! 202:
! 203: #endif
! 204:
! 205:
! 206: #elif ( __sparc__ || __sparc || __sparcv9 )
! 207:
! 208: #if (NGX_PTR_SIZE == 8)
! 209:
! 210: typedef int64_t ngx_atomic_int_t;
! 211: typedef uint64_t ngx_atomic_uint_t;
! 212: #define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
! 213:
! 214: #else
! 215:
! 216: typedef int32_t ngx_atomic_int_t;
! 217: typedef uint32_t ngx_atomic_uint_t;
! 218: #define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
! 219:
! 220: #endif
! 221:
! 222: typedef volatile ngx_atomic_uint_t ngx_atomic_t;
! 223:
! 224:
! 225: #if ( __SUNPRO_C )
! 226:
! 227: #define NGX_HAVE_ATOMIC_OPS 1
! 228:
! 229: #include "ngx_sunpro_atomic_sparc64.h"
! 230:
! 231:
! 232: #else /* ( __GNUC__ || __INTEL_COMPILER ) */
! 233:
! 234: #define NGX_HAVE_ATOMIC_OPS 1
! 235:
! 236: #include "ngx_gcc_atomic_sparc64.h"
! 237:
! 238: #endif
! 239:
! 240:
! 241: #elif ( __powerpc__ || __POWERPC__ )
! 242:
! 243: #define NGX_HAVE_ATOMIC_OPS 1
! 244:
! 245: #if (NGX_PTR_SIZE == 8)
! 246:
! 247: typedef int64_t ngx_atomic_int_t;
! 248: typedef uint64_t ngx_atomic_uint_t;
! 249: #define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
! 250:
! 251: #else
! 252:
! 253: typedef int32_t ngx_atomic_int_t;
! 254: typedef uint32_t ngx_atomic_uint_t;
! 255: #define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
! 256:
! 257: #endif
! 258:
! 259: typedef volatile ngx_atomic_uint_t ngx_atomic_t;
! 260:
! 261:
! 262: #include "ngx_gcc_atomic_ppc.h"
! 263:
! 264: #endif
! 265:
! 266:
! 267: #if !(NGX_HAVE_ATOMIC_OPS)
! 268:
! 269: #define NGX_HAVE_ATOMIC_OPS 0
! 270:
! 271: typedef int32_t ngx_atomic_int_t;
! 272: typedef uint32_t ngx_atomic_uint_t;
! 273: typedef volatile ngx_atomic_uint_t ngx_atomic_t;
! 274: #define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
! 275:
! 276:
! 277: static ngx_inline ngx_atomic_uint_t
! 278: ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
! 279: ngx_atomic_uint_t set)
! 280: {
! 281: if (*lock == old) {
! 282: *lock = set;
! 283: return 1;
! 284: }
! 285:
! 286: return 0;
! 287: }
! 288:
! 289:
! 290: static ngx_inline ngx_atomic_int_t
! 291: ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
! 292: {
! 293: ngx_atomic_int_t old;
! 294:
! 295: old = *value;
! 296: *value += add;
! 297:
! 298: return old;
! 299: }
! 300:
! 301: #define ngx_memory_barrier()
! 302: #define ngx_cpu_pause()
! 303:
! 304: #endif
! 305:
! 306:
! 307: void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);
! 308:
! 309: #define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
! 310: #define ngx_unlock(lock) *(lock) = 0
! 311:
! 312:
! 313: #endif /* _NGX_ATOMIC_H_INCLUDED_ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>