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

Functions defined

Macros defined

Source code


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


  5. #if (NGX_SMP)
  6. #define NGX_SMP_LOCK  "lock;"
  7. #else
  8. #define NGX_SMP_LOCK
  9. #endif


  10. /*
  11. * "cmpxchgq  r, [m]":
  12. *
  13. *     if (rax == [m]) {
  14. *         zf = 1;
  15. *         [m] = r;
  16. *     } else {
  17. *         zf = 0;
  18. *         rax = [m];
  19. *     }
  20. *
  21. *
  22. * The "r" is any register, %rax (%r0) - %r16.
  23. * The "=a" and "a" are the %rax register.
  24. * Although we can return result in any register, we use "a" because it is
  25. * used in cmpxchgq anyway.  The result is actually in %al but not in $rax,
  26. * however as the code is inlined gcc can test %al as well as %rax.
  27. *
  28. * The "cc" means that flags were changed.
  29. */

  30. static ngx_inline ngx_atomic_uint_t
  31. ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
  32.     ngx_atomic_uint_t set)
  33. {
  34.     u_char  res;

  35.     __asm__ volatile (

  36.          NGX_SMP_LOCK
  37.     "    cmpxchgq  %3, %1;   "
  38.     "    sete      %0;       "

  39.     : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");

  40.     return res;
  41. }


  42. /*
  43. * "xaddq  r, [m]":
  44. *
  45. *     temp = [m];
  46. *     [m] += r;
  47. *     r = temp;
  48. *
  49. *
  50. * The "+r" is any register, %rax (%r0) - %r16.
  51. * The "cc" means that flags were changed.
  52. */

  53. static ngx_inline ngx_atomic_int_t
  54. ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
  55. {
  56.     __asm__ volatile (

  57.          NGX_SMP_LOCK
  58.     "    xaddq  %0, %1;   "

  59.     : "+r" (add) : "m" (*value) : "cc", "memory");

  60.     return add;
  61. }


  62. #define ngx_memory_barrier()    __asm__ volatile ("" ::: "memory")

  63. #define ngx_cpu_pause()         __asm__ ("pause")