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

Functions defined

Macros defined

Source code


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


  5. /*
  6. * The ppc assembler treats ";" as comment, so we have to use "\n".
  7. * The minus in "bne-" is a hint for the branch prediction unit that
  8. * this branch is unlikely to be taken.
  9. * The "1b" means the nearest backward label "1" and the "1f" means
  10. * the nearest forward label "1".
  11. *
  12. * The "b" means that the base registers can be used only, i.e.
  13. * any register except r0.  The r0 register always has a zero value and
  14. * could not be used in "addi  r0, r0, 1".
  15. * The "=&b" means that no input registers can be used.
  16. *
  17. * "sync"    read and write barriers
  18. * "isync"   read barrier, is faster than "sync"
  19. * "eieio"   write barrier, is faster than "sync"
  20. * "lwsync"  write barrier, is faster than "eieio" on ppc64
  21. */

  22. #if (NGX_PTR_SIZE == 8)

  23. static ngx_inline ngx_atomic_uint_t
  24. ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
  25.     ngx_atomic_uint_t set)
  26. {
  27.     ngx_atomic_uint_t  res, temp;

  28.     __asm__ volatile (

  29.     "    li      %0, 0       \n" /* preset "0" to "res"                      */
  30.     "    lwsync              \n" /* write barrier                            */
  31.     "1:                      \n"
  32.     "    ldarx   %1, 0, %2   \n" /* load from [lock] into "temp"             */
  33.                                  /*   and store reservation                  */
  34.     "    cmpd    %1, %3      \n" /* compare "temp" and "old"                 */
  35.     "    bne-    2f          \n" /* not equal                                */
  36.     "    stdcx.  %4, 0, %2   \n" /* store "set" into [lock] if reservation   */
  37.                                  /*   is not cleared                         */
  38.     "    bne-    1b          \n" /* the reservation was cleared              */
  39.     "    isync               \n" /* read barrier                             */
  40.     "    li      %0, 1       \n" /* set "1" to "res"                         */
  41.     "2:                      \n"

  42.     : "=&b" (res), "=&b" (temp)
  43.     : "b" (lock), "b" (old), "b" (set)
  44.     : "cc", "memory");

  45.     return res;
  46. }


  47. static ngx_inline ngx_atomic_int_t
  48. ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
  49. {
  50.     ngx_atomic_uint_t  res, temp;

  51.     __asm__ volatile (

  52.     "    lwsync              \n" /* write barrier                            */
  53.     "1:  ldarx   %0, 0, %2   \n" /* load from [value] into "res"             */
  54.                                  /*   and store reservation                  */
  55.     "    add     %1, %0, %3  \n" /* "res" + "add" store in "temp"            */
  56.     "    stdcx.  %1, 0, %2   \n" /* store "temp" into [value] if reservation */
  57.                                  /*   is not cleared                         */
  58.     "    bne-    1b          \n" /* try again if reservation was cleared     */
  59.     "    isync               \n" /* read barrier                             */

  60.     : "=&b" (res), "=&b" (temp)
  61.     : "b" (value), "b" (add)
  62.     : "cc", "memory");

  63.     return res;
  64. }


  65. #if (NGX_SMP)
  66. #define ngx_memory_barrier()                                                  \
  67.     __asm__ volatile ("isync  \n  lwsync  \n" ::: "memory")
  68. #else
  69. #define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
  70. #endif

  71. #else

  72. static ngx_inline ngx_atomic_uint_t
  73. ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
  74.     ngx_atomic_uint_t set)
  75. {
  76.     ngx_atomic_uint_t  res, temp;

  77.     __asm__ volatile (

  78.     "    li      %0, 0       \n" /* preset "0" to "res"                      */
  79.     "    eieio               \n" /* write barrier                            */
  80.     "1:                      \n"
  81.     "    lwarx   %1, 0, %2   \n" /* load from [lock] into "temp"             */
  82.                                  /*   and store reservation                  */
  83.     "    cmpw    %1, %3      \n" /* compare "temp" and "old"                 */
  84.     "    bne-    2f          \n" /* not equal                                */
  85.     "    stwcx.  %4, 0, %2   \n" /* store "set" into [lock] if reservation   */
  86.                                  /*   is not cleared                         */
  87.     "    bne-    1b          \n" /* the reservation was cleared              */
  88.     "    isync               \n" /* read barrier                             */
  89.     "    li      %0, 1       \n" /* set "1" to "res"                         */
  90.     "2:                      \n"

  91.     : "=&b" (res), "=&b" (temp)
  92.     : "b" (lock), "b" (old), "b" (set)
  93.     : "cc", "memory");

  94.     return res;
  95. }


  96. static ngx_inline ngx_atomic_int_t
  97. ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
  98. {
  99.     ngx_atomic_uint_t  res, temp;

  100.     __asm__ volatile (

  101.     "    eieio               \n" /* write barrier                            */
  102.     "1:  lwarx   %0, 0, %2   \n" /* load from [value] into "res"             */
  103.                                  /*   and store reservation                  */
  104.     "    add     %1, %0, %3  \n" /* "res" + "add" store in "temp"            */
  105.     "    stwcx.  %1, 0, %2   \n" /* store "temp" into [value] if reservation */
  106.                                  /*   is not cleared                         */
  107.     "    bne-    1b          \n" /* try again if reservation was cleared     */
  108.     "    isync               \n" /* read barrier                             */

  109.     : "=&b" (res), "=&b" (temp)
  110.     : "b" (value), "b" (add)
  111.     : "cc", "memory");

  112.     return res;
  113. }


  114. #if (NGX_SMP)
  115. #define ngx_memory_barrier()                                                  \
  116.     __asm__ volatile ("isync  \n  eieio  \n" ::: "memory")
  117. #else
  118. #define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
  119. #endif

  120. #endif


  121. #define ngx_cpu_pause()