src/os/unix/ngx_atomic.h - nginx-1.7.10

Data types defined

Functions defined

Macros defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #ifndef _NGX_ATOMIC_H_INCLUDED_
  6. #define _NGX_ATOMIC_H_INCLUDED_


  7. #include <ngx_config.h>
  8. #include <ngx_core.h>


  9. #if (NGX_HAVE_LIBATOMIC)

  10. #define AO_REQUIRE_CAS
  11. #include <atomic_ops.h>

  12. #define NGX_HAVE_ATOMIC_OPS  1

  13. typedef long                        ngx_atomic_int_t;
  14. typedef AO_t                        ngx_atomic_uint_t;
  15. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;

  16. #if (NGX_PTR_SIZE == 8)
  17. #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)
  18. #else
  19. #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
  20. #endif

  21. #define ngx_atomic_cmp_set(lock, old, new)                                    \
  22.     AO_compare_and_swap(lock, old, new)
  23. #define ngx_atomic_fetch_add(value, add)                                      \
  24.     AO_fetch_and_add(value, add)
  25. #define ngx_memory_barrier()        AO_nop()
  26. #define ngx_cpu_pause()


  27. #elif (NGX_DARWIN_ATOMIC)

  28. /*
  29. * use Darwin 8 atomic(3) and barrier(3) operations
  30. * optimized at run-time for UP and SMP
  31. */

  32. #include <libkern/OSAtomic.h>

  33. /* "bool" conflicts with perl's CORE/handy.h */
  34. #if 0
  35. #undef bool
  36. #endif


  37. #define NGX_HAVE_ATOMIC_OPS  1

  38. #if (NGX_PTR_SIZE == 8)

  39. typedef int64_t                     ngx_atomic_int_t;
  40. typedef uint64_t                    ngx_atomic_uint_t;
  41. #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)

  42. #define ngx_atomic_cmp_set(lock, old, new)                                    \
  43.     OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)

  44. #define ngx_atomic_fetch_add(value, add)                                      \
  45.     (OSAtomicAdd64(add, (int64_t *) value) - add)

  46. #else

  47. typedef int32_t                     ngx_atomic_int_t;
  48. typedef uint32_t                    ngx_atomic_uint_t;
  49. #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)

  50. #define ngx_atomic_cmp_set(lock, old, new)                                    \
  51.     OSAtomicCompareAndSwap32Barrier(old, new, (int32_t *) lock)

  52. #define ngx_atomic_fetch_add(value, add)                                      \
  53.     (OSAtomicAdd32(add, (int32_t *) value) - add)

  54. #endif

  55. #define ngx_memory_barrier()        OSMemoryBarrier()

  56. #define ngx_cpu_pause()

  57. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;


  58. #elif (NGX_HAVE_GCC_ATOMIC)

  59. /* GCC 4.1 builtin atomic operations */

  60. #define NGX_HAVE_ATOMIC_OPS  1

  61. typedef long                        ngx_atomic_int_t;
  62. typedef unsigned long               ngx_atomic_uint_t;

  63. #if (NGX_PTR_SIZE == 8)
  64. #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)
  65. #else
  66. #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
  67. #endif

  68. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;


  69. #define ngx_atomic_cmp_set(lock, old, set)                                    \
  70.     __sync_bool_compare_and_swap(lock, old, set)

  71. #define ngx_atomic_fetch_add(value, add)                                      \
  72.     __sync_fetch_and_add(value, add)

  73. #define ngx_memory_barrier()        __sync_synchronize()

  74. #if ( __i386__ || __i386 || __amd64__ || __amd64 )
  75. #define ngx_cpu_pause()             __asm__ ("pause")
  76. #else
  77. #define ngx_cpu_pause()
  78. #endif


  79. #elif ( __i386__ || __i386 )

  80. typedef int32_t                     ngx_atomic_int_t;
  81. typedef uint32_t                    ngx_atomic_uint_t;
  82. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
  83. #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)


  84. #if ( __SUNPRO_C )

  85. #define NGX_HAVE_ATOMIC_OPS  1

  86. ngx_atomic_uint_t
  87. ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
  88.     ngx_atomic_uint_t set);

  89. ngx_atomic_int_t
  90. ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);

  91. /*
  92. * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
  93. * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_x86.il
  94. */

  95. void
  96. ngx_cpu_pause(void);

  97. /* the code in src/os/unix/ngx_sunpro_x86.il */

  98. #define ngx_memory_barrier()        __asm (".volatile"); __asm (".nonvolatile")


  99. #else /* ( __GNUC__ || __INTEL_COMPILER ) */

  100. #define NGX_HAVE_ATOMIC_OPS  1

  101. #include "ngx_gcc_atomic_x86.h"

  102. #endif


  103. #elif ( __amd64__ || __amd64 )

  104. typedef int64_t                     ngx_atomic_int_t;
  105. typedef uint64_t                    ngx_atomic_uint_t;
  106. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
  107. #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)


  108. #if ( __SUNPRO_C )

  109. #define NGX_HAVE_ATOMIC_OPS  1

  110. ngx_atomic_uint_t
  111. ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
  112.     ngx_atomic_uint_t set);

  113. ngx_atomic_int_t
  114. ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);

  115. /*
  116. * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
  117. * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_amd64.il
  118. */

  119. void
  120. ngx_cpu_pause(void);

  121. /* the code in src/os/unix/ngx_sunpro_amd64.il */

  122. #define ngx_memory_barrier()        __asm (".volatile"); __asm (".nonvolatile")


  123. #else /* ( __GNUC__ || __INTEL_COMPILER ) */

  124. #define NGX_HAVE_ATOMIC_OPS  1

  125. #include "ngx_gcc_atomic_amd64.h"

  126. #endif


  127. #elif ( __sparc__ || __sparc || __sparcv9 )

  128. #if (NGX_PTR_SIZE == 8)

  129. typedef int64_t                     ngx_atomic_int_t;
  130. typedef uint64_t                    ngx_atomic_uint_t;
  131. #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)

  132. #else

  133. typedef int32_t                     ngx_atomic_int_t;
  134. typedef uint32_t                    ngx_atomic_uint_t;
  135. #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)

  136. #endif

  137. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;


  138. #if ( __SUNPRO_C )

  139. #define NGX_HAVE_ATOMIC_OPS  1

  140. #include "ngx_sunpro_atomic_sparc64.h"


  141. #else /* ( __GNUC__ || __INTEL_COMPILER ) */

  142. #define NGX_HAVE_ATOMIC_OPS  1

  143. #include "ngx_gcc_atomic_sparc64.h"

  144. #endif


  145. #elif ( __powerpc__ || __POWERPC__ )

  146. #define NGX_HAVE_ATOMIC_OPS  1

  147. #if (NGX_PTR_SIZE == 8)

  148. typedef int64_t                     ngx_atomic_int_t;
  149. typedef uint64_t                    ngx_atomic_uint_t;
  150. #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)

  151. #else

  152. typedef int32_t                     ngx_atomic_int_t;
  153. typedef uint32_t                    ngx_atomic_uint_t;
  154. #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)

  155. #endif

  156. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;


  157. #include "ngx_gcc_atomic_ppc.h"

  158. #endif


  159. #if !(NGX_HAVE_ATOMIC_OPS)

  160. #define NGX_HAVE_ATOMIC_OPS  0

  161. typedef int32_t                     ngx_atomic_int_t;
  162. typedef uint32_t                    ngx_atomic_uint_t;
  163. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
  164. #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)


  165. static ngx_inline ngx_atomic_uint_t
  166. ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
  167.      ngx_atomic_uint_t set)
  168. {
  169.      if (*lock == old) {
  170.          *lock = set;
  171.          return 1;
  172.      }

  173.      return 0;
  174. }


  175. static ngx_inline ngx_atomic_int_t
  176. ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
  177. {
  178.      ngx_atomic_int_t  old;

  179.      old = *value;
  180.      *value += add;

  181.      return old;
  182. }

  183. #define ngx_memory_barrier()
  184. #define ngx_cpu_pause()

  185. #endif


  186. void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);

  187. #define ngx_trylock(lock)  (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
  188. #define ngx_unlock(lock)    *(lock) = 0


  189. #endif /* _NGX_ATOMIC_H_INCLUDED_ */