Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.12 ]​[ nginx-1.16.0 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 /*
0009  * The ppc assembler treats ";" as comment, so we have to use "\n".
0010  * The minus in "bne-" is a hint for the branch prediction unit that
0011  * this branch is unlikely to be taken.
0012  * The "1b" means the nearest backward label "1" and the "1f" means
0013  * the nearest forward label "1".
0014  *
0015  * The "b" means that the base registers can be used only, i.e.
0016  * any register except r0.  The r0 register always has a zero value and
0017  * could not be used in "addi  r0, r0, 1".
0018  * The "=&b" means that no input registers can be used.
0019  *
0020  * "sync"    read and write barriers
0021  * "isync"   read barrier, is faster than "sync"
0022  * "eieio"   write barrier, is faster than "sync"
0023  * "lwsync"  write barrier, is faster than "eieio" on ppc64
0024  */
0025 
0026 #if (NGX_PTR_SIZE == 8)
0027 
0028 static ngx_inline ngx_atomic_uint_t
0029 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
0030     ngx_atomic_uint_t set)
0031 {
0032     ngx_atomic_uint_t  res, temp;
0033 
0034     __asm__ volatile (
0035 
0036     "    li      %0, 0       \n" /* preset "0" to "res"                      */
0037     "    lwsync              \n" /* write barrier                            */
0038     "1:                      \n"
0039     "    ldarx   %1, 0, %2   \n" /* load from [lock] into "temp"             */
0040                                  /*   and store reservation                  */
0041     "    cmpd    %1, %3      \n" /* compare "temp" and "old"                 */
0042     "    bne-    2f          \n" /* not equal                                */
0043     "    stdcx.  %4, 0, %2   \n" /* store "set" into [lock] if reservation   */
0044                                  /*   is not cleared                         */
0045     "    bne-    1b          \n" /* the reservation was cleared              */
0046     "    isync               \n" /* read barrier                             */
0047     "    li      %0, 1       \n" /* set "1" to "res"                         */
0048     "2:                      \n"
0049 
0050     : "=&b" (res), "=&b" (temp)
0051     : "b" (lock), "b" (old), "b" (set)
0052     : "cc", "memory");
0053 
0054     return res;
0055 }
0056 
0057 
0058 static ngx_inline ngx_atomic_int_t
0059 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
0060 {
0061     ngx_atomic_uint_t  res, temp;
0062 
0063     __asm__ volatile (
0064 
0065     "    lwsync              \n" /* write barrier                            */
0066     "1:  ldarx   %0, 0, %2   \n" /* load from [value] into "res"             */
0067                                  /*   and store reservation                  */
0068     "    add     %1, %0, %3  \n" /* "res" + "add" store in "temp"            */
0069     "    stdcx.  %1, 0, %2   \n" /* store "temp" into [value] if reservation */
0070                                  /*   is not cleared                         */
0071     "    bne-    1b          \n" /* try again if reservation was cleared     */
0072     "    isync               \n" /* read barrier                             */
0073 
0074     : "=&b" (res), "=&b" (temp)
0075     : "b" (value), "b" (add)
0076     : "cc", "memory");
0077 
0078     return res;
0079 }
0080 
0081 
0082 #if (NGX_SMP)
0083 #define ngx_memory_barrier()                                                  \
0084     __asm__ volatile ("isync  \n  lwsync  \n" ::: "memory")
0085 #else
0086 #define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
0087 #endif
0088 
0089 #else
0090 
0091 static ngx_inline ngx_atomic_uint_t
0092 ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
0093     ngx_atomic_uint_t set)
0094 {
0095     ngx_atomic_uint_t  res, temp;
0096 
0097     __asm__ volatile (
0098 
0099     "    li      %0, 0       \n" /* preset "0" to "res"                      */
0100     "    eieio               \n" /* write barrier                            */
0101     "1:                      \n"
0102     "    lwarx   %1, 0, %2   \n" /* load from [lock] into "temp"             */
0103                                  /*   and store reservation                  */
0104     "    cmpw    %1, %3      \n" /* compare "temp" and "old"                 */
0105     "    bne-    2f          \n" /* not equal                                */
0106     "    stwcx.  %4, 0, %2   \n" /* store "set" into [lock] if reservation   */
0107                                  /*   is not cleared                         */
0108     "    bne-    1b          \n" /* the reservation was cleared              */
0109     "    isync               \n" /* read barrier                             */
0110     "    li      %0, 1       \n" /* set "1" to "res"                         */
0111     "2:                      \n"
0112 
0113     : "=&b" (res), "=&b" (temp)
0114     : "b" (lock), "b" (old), "b" (set)
0115     : "cc", "memory");
0116 
0117     return res;
0118 }
0119 
0120 
0121 static ngx_inline ngx_atomic_int_t
0122 ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
0123 {
0124     ngx_atomic_uint_t  res, temp;
0125 
0126     __asm__ volatile (
0127 
0128     "    eieio               \n" /* write barrier                            */
0129     "1:  lwarx   %0, 0, %2   \n" /* load from [value] into "res"             */
0130                                  /*   and store reservation                  */
0131     "    add     %1, %0, %3  \n" /* "res" + "add" store in "temp"            */
0132     "    stwcx.  %1, 0, %2   \n" /* store "temp" into [value] if reservation */
0133                                  /*   is not cleared                         */
0134     "    bne-    1b          \n" /* try again if reservation was cleared     */
0135     "    isync               \n" /* read barrier                             */
0136 
0137     : "=&b" (res), "=&b" (temp)
0138     : "b" (value), "b" (add)
0139     : "cc", "memory");
0140 
0141     return res;
0142 }
0143 
0144 
0145 #if (NGX_SMP)
0146 #define ngx_memory_barrier()                                                  \
0147     __asm__ volatile ("isync  \n  eieio  \n" ::: "memory")
0148 #else
0149 #define ngx_memory_barrier()   __asm__ volatile ("" ::: "memory")
0150 #endif
0151 
0152 #endif
0153 
0154 
0155 #define ngx_cpu_pause()