Annotation of embedaddon/nginx/src/os/unix/ngx_gcc_atomic_ppc.h, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (C) Igor Sysoev
                      4:  * Copyright (C) Nginx, Inc.
                      5:  */
                      6: 
                      7: 
                      8: /*
                      9:  * The ppc assembler treats ";" as comment, so we have to use "\n".
                     10:  * The minus in "bne-" is a hint for the branch prediction unit that
                     11:  * this branch is unlikely to be taken.
                     12:  * The "1b" means the nearest backward label "1" and the "1f" means
                     13:  * the nearest forward label "1".
                     14:  *
                     15:  * The "b" means that the base registers can be used only, i.e.
                     16:  * any register except r0.  The r0 register always has a zero value and
                     17:  * could not be used in "addi  r0, r0, 1".
                     18:  * The "=&b" means that no input registers can be used.
                     19:  *
                     20:  * "sync"    read and write barriers
                     21:  * "isync"   read barrier, is faster than "sync"
                     22:  * "eieio"   write barrier, is faster than "sync"
                     23:  * "lwsync"  write barrier, is faster than "eieio" on ppc64
                     24:  */
                     25: 
                     26: #if (NGX_PTR_SIZE == 8)
                     27: 
                     28: static ngx_inline ngx_atomic_uint_t
                     29: ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
                     30:     ngx_atomic_uint_t set)
                     31: {
                     32:     ngx_atomic_uint_t  res, temp;
                     33: 
                     34:     __asm__ volatile (
                     35: 
                     36:     "    li      %0, 0       \n" /* preset "0" to "res"                      */
                     37:     "    lwsync              \n" /* write barrier                            */
                     38:     "1:                      \n"
                     39:     "    ldarx   %1, 0, %2   \n" /* load from [lock] into "temp"             */
                     40:                                  /*   and store reservation                  */
                     41:     "    cmpd    %1, %3      \n" /* compare "temp" and "old"                 */
                     42:     "    bne-    2f          \n" /* not equal                                */
                     43:     "    stdcx.  %4, 0, %2   \n" /* store "set" into [lock] if reservation   */
                     44:                                  /*   is not cleared                         */
                     45:     "    bne-    1b          \n" /* the reservation was cleared              */
                     46:     "    isync               \n" /* read barrier                             */
                     47:     "    li      %0, 1       \n" /* set "1" to "res"                         */
                     48:     "2:                      \n"
                     49: 
                     50:     : "=&b" (res), "=&b" (temp)
                     51:     : "b" (lock), "b" (old), "b" (set)
                     52:     : "cc", "memory");
                     53: 
                     54:     return res;
                     55: }
                     56: 
                     57: 
                     58: static ngx_inline ngx_atomic_int_t
                     59: ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
                     60: {
                     61:     ngx_atomic_uint_t  res, temp;
                     62: 
                     63:     __asm__ volatile (
                     64: 
                     65:     "    lwsync              \n" /* write barrier                            */
                     66:     "1:  ldarx   %0, 0, %2   \n" /* load from [value] into "res"             */
                     67:                                  /*   and store reservation                  */
                     68:     "    add     %1, %0, %3  \n" /* "res" + "add" store in "temp"            */
                     69:     "    stdcx.  %1, 0, %2   \n" /* store "temp" into [value] if reservation */
                     70:                                  /*   is not cleared                         */
                     71:     "    bne-    1b          \n" /* try again if reservation was cleared     */
                     72:     "    isync               \n" /* read barrier                             */
                     73: 
                     74:     : "=&b" (res), "=&b" (temp)
                     75:     : "b" (value), "b" (add)
                     76:     : "cc", "memory");
                     77: 
                     78:     return res;
                     79: }
                     80: 
                     81: 
                     82: #if (NGX_SMP)
                     83: #define ngx_memory_barrier()                                                  \
                     84:     __asm__ volatile ("isync  \n  lwsync  \n" ::: "memory")
                     85: #else
                     86: #define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
                     87: #endif
                     88: 
                     89: #else
                     90: 
                     91: static ngx_inline ngx_atomic_uint_t
                     92: ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
                     93:     ngx_atomic_uint_t set)
                     94: {
                     95:     ngx_atomic_uint_t  res, temp;
                     96: 
                     97:     __asm__ volatile (
                     98: 
                     99:     "    li      %0, 0       \n" /* preset "0" to "res"                      */
                    100:     "    eieio               \n" /* write barrier                            */
                    101:     "1:                      \n"
                    102:     "    lwarx   %1, 0, %2   \n" /* load from [lock] into "temp"             */
                    103:                                  /*   and store reservation                  */
                    104:     "    cmpw    %1, %3      \n" /* compare "temp" and "old"                 */
                    105:     "    bne-    2f          \n" /* not equal                                */
                    106:     "    stwcx.  %4, 0, %2   \n" /* store "set" into [lock] if reservation   */
                    107:                                  /*   is not cleared                         */
                    108:     "    bne-    1b          \n" /* the reservation was cleared              */
                    109:     "    isync               \n" /* read barrier                             */
                    110:     "    li      %0, 1       \n" /* set "1" to "res"                         */
                    111:     "2:                      \n"
                    112: 
                    113:     : "=&b" (res), "=&b" (temp)
                    114:     : "b" (lock), "b" (old), "b" (set)
                    115:     : "cc", "memory");
                    116: 
                    117:     return res;
                    118: }
                    119: 
                    120: 
                    121: static ngx_inline ngx_atomic_int_t
                    122: ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
                    123: {
                    124:     ngx_atomic_uint_t  res, temp;
                    125: 
                    126:     __asm__ volatile (
                    127: 
                    128:     "    eieio               \n" /* write barrier                            */
                    129:     "1:  lwarx   %0, 0, %2   \n" /* load from [value] into "res"             */
                    130:                                  /*   and store reservation                  */
                    131:     "    add     %1, %0, %3  \n" /* "res" + "add" store in "temp"            */
                    132:     "    stwcx.  %1, 0, %2   \n" /* store "temp" into [value] if reservation */
                    133:                                  /*   is not cleared                         */
                    134:     "    bne-    1b          \n" /* try again if reservation was cleared     */
                    135:     "    isync               \n" /* read barrier                             */
                    136: 
                    137:     : "=&b" (res), "=&b" (temp)
                    138:     : "b" (value), "b" (add)
                    139:     : "cc", "memory");
                    140: 
                    141:     return res;
                    142: }
                    143: 
                    144: 
                    145: #if (NGX_SMP)
                    146: #define ngx_memory_barrier()                                                  \
                    147:     __asm__ volatile ("isync  \n  eieio  \n" ::: "memory")
                    148: #else
                    149: #define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
                    150: #endif
                    151: 
                    152: #endif
                    153: 
                    154: 
                    155: #define ngx_cpu_pause()

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>