src/os/unix/ngx_atomic.h - nginx source code

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_HAVE_GCC_ATOMIC)

  28. /* GCC 4.1 builtin atomic operations */

  29. #define NGX_HAVE_ATOMIC_OPS  1

  30. typedef long                        ngx_atomic_int_t;
  31. typedef unsigned long               ngx_atomic_uint_t;

  32. #if (NGX_PTR_SIZE == 8)
  33. #define NGX_ATOMIC_T_LEN            (sizeof("-9223372036854775808") - 1)
  34. #else
  35. #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)
  36. #endif

  37. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;


  38. #define ngx_atomic_cmp_set(lock, old, set)                                    \
  39.     __sync_bool_compare_and_swap(lock, old, set)

  40. #define ngx_atomic_fetch_add(value, add)                                      \
  41.     __sync_fetch_and_add(value, add)

  42. #define ngx_memory_barrier()        __sync_synchronize()

  43. #if ( __i386__ || __i386 || __amd64__ || __amd64 )
  44. #define ngx_cpu_pause()             __asm__ ("pause")
  45. #else
  46. #define ngx_cpu_pause()
  47. #endif


  48. #elif (NGX_DARWIN_ATOMIC)

  49. /*
  50. * use Darwin 8 atomic(3) and barrier(3) operations
  51. * optimized at run-time for UP and SMP
  52. */

  53. #include <libkern/OSAtomic.h>

  54. /* "bool" conflicts with perl's CORE/handy.h */
  55. #if 0
  56. #undef bool
  57. #endif


  58. #define NGX_HAVE_ATOMIC_OPS  1

  59. #if (NGX_PTR_SIZE == 8)

  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. #define ngx_atomic_cmp_set(lock, old, new)                                    \
  64.     OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)

  65. #define ngx_atomic_fetch_add(value, add)                                      \
  66.     (OSAtomicAdd64(add, (int64_t *) value) - add)

  67. #else

  68. typedef int32_t                     ngx_atomic_int_t;
  69. typedef uint32_t                    ngx_atomic_uint_t;
  70. #define NGX_ATOMIC_T_LEN            (sizeof("-2147483648") - 1)

  71. #define ngx_atomic_cmp_set(lock, old, new)                                    \
  72.     OSAtomicCompareAndSwap32Barrier(old, new, (int32_t *) lock)

  73. #define ngx_atomic_fetch_add(value, add)                                      \
  74.     (OSAtomicAdd32(add, (int32_t *) value) - add)

  75. #endif

  76. #define ngx_memory_barrier()        OSMemoryBarrier()

  77. #define ngx_cpu_pause()

  78. typedef volatile ngx_atomic_uint_t  ngx_atomic_t;


  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_ */