Mercurial > hg > nginx-vendor-0-6
diff src/os/unix/ngx_gcc_atomic_ppc.h @ 270:6eb1e38f0f1f NGINX_0_5_5
nginx 0.5.5
*) Change: the -v switch does not show compiler information any more.
*) Feature: the -V switch.
*) Feature: the "worker_rlimit_core" directive supports size in K, M,
and G.
*) Bugfix: the nginx.pm module now could be installed by an
unprivileged user.
*) Bugfix: a segmentation fault might occur if the $r->request_body or
$r->request_body_file methods were used.
*) Bugfix: the ppc platform specific bugs.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Sun, 24 Dec 2006 00:00:00 +0300 |
parents | 73e8476f9142 |
children |
line wrap: on
line diff
--- a/src/os/unix/ngx_gcc_atomic_ppc.h +++ b/src/os/unix/ngx_gcc_atomic_ppc.h @@ -15,8 +15,15 @@ * any register except r0. The r0 register always has a zero value and * could not be used in "addi r0, r0, 1". * The "=&b" means that no input registers can be used. + * + * "sync" read and write barriers + * "isync" read barrier, is faster than "sync" + * "eieio" write barrier, is faster than "sync" + * "lwsync" write barrier, is faster than "eieio" on ppc64 */ +#if (NGX_PTR_SIZE == 8) + static ngx_inline ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, ngx_atomic_uint_t set) @@ -26,15 +33,18 @@ ngx_atomic_cmp_set(ngx_atomic_t *lock, n __asm__ volatile ( " li %0, 0 \n" /* preset "0" to "res" */ - " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */ + " lwsync \n" /* write barrier */ + "1: \n" + " ldarx %1, 0, %2 \n" /* load from [lock] into "temp" */ /* and store reservation */ - " cmpw %1, %3 \n" /* compare "temp" and "old" */ - " bne- 1f \n" /* not equal */ - " stwcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */ + " cmpd %1, %3 \n" /* compare "temp" and "old" */ + " bne- 2f \n" /* not equal */ + " stdcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */ /* is not cleared */ - " bne- 1f \n" /* the reservation was cleared */ + " bne- 1b \n" /* the reservation was cleared */ + " isync \n" /* read barrier */ " li %0, 1 \n" /* set "1" to "res" */ - "1: \n" + "2: \n" : "=&b" (res), "=&b" (temp) : "b" (lock), "b" (old), "b" (set) @@ -51,12 +61,14 @@ ngx_atomic_fetch_add(ngx_atomic_t *value __asm__ volatile ( - "1: lwarx %0, 0, %2 \n" /* load from [value] into "res" */ + " lwsync \n" /* write barrier */ + "1: ldarx %0, 0, %2 \n" /* load from [value] into "res" */ /* and store reservation */ " add %1, %0, %3 \n" /* "res" + "add" store in "temp" */ - " stwcx. %1, 0, %2 \n" /* store "temp" into [value] if reservation */ + " stdcx. %1, 0, %2 \n" /* store "temp" into [value] if reservation */ /* is not cleared */ " bne- 1b \n" /* try again if reservation was cleared */ + " isync \n" /* read barrier */ : "=&b" (res), "=&b" (temp) : "b" (value), "b" (add) @@ -67,9 +79,76 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #if (NGX_SMP) -#define ngx_memory_barrier() __asm__ volatile ("sync\n" ::: "memory") +#define ngx_memory_barrier() \ + __asm__ volatile ("isync \n lwsync \n" ::: "memory") #else #define ngx_memory_barrier() __asm__ volatile ("" ::: "memory") #endif +#else + +static ngx_inline ngx_atomic_uint_t +ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, + ngx_atomic_uint_t set) +{ + ngx_atomic_uint_t res, temp; + + __asm__ volatile ( + + " li %0, 0 \n" /* preset "0" to "res" */ + " eieio \n" /* write barrier */ + "1: \n" + " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */ + /* and store reservation */ + " cmpw %1, %3 \n" /* compare "temp" and "old" */ + " bne- 2f \n" /* not equal */ + " stwcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */ + /* is not cleared */ + " bne- 1b \n" /* the reservation was cleared */ + " isync \n" /* read barrier */ + " li %0, 1 \n" /* set "1" to "res" */ + "2: \n" + + : "=&b" (res), "=&b" (temp) + : "b" (lock), "b" (old), "b" (set) + : "cc", "memory"); + + return res; +} + + +static ngx_inline ngx_atomic_int_t +ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add) +{ + ngx_atomic_uint_t res, temp; + + __asm__ volatile ( + + " eieio \n" /* write barrier */ + "1: lwarx %0, 0, %2 \n" /* load from [value] into "res" */ + /* and store reservation */ + " add %1, %0, %3 \n" /* "res" + "add" store in "temp" */ + " stwcx. %1, 0, %2 \n" /* store "temp" into [value] if reservation */ + /* is not cleared */ + " bne- 1b \n" /* try again if reservation was cleared */ + " isync \n" /* read barrier */ + + : "=&b" (res), "=&b" (temp) + : "b" (value), "b" (add) + : "cc", "memory"); + + return res; +} + + +#if (NGX_SMP) +#define ngx_memory_barrier() \ + __asm__ volatile ("isync \n eieio \n" ::: "memory") +#else +#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory") +#endif + +#endif + + #define ngx_cpu_pause()