changeset 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 aa9c0062124d
children fcbee7dacf2b
files CHANGES CHANGES.ru auto/cc/name auto/feature auto/lib/perl/conf auto/lib/perl/make auto/os/conf configure src/core/nginx.c src/core/nginx.h src/core/ngx_crc32.c src/core/ngx_crc32.h src/core/ngx_cycle.c src/core/ngx_cycle.h src/core/ngx_log.c src/core/ngx_palloc.c src/core/ngx_times.c src/event/modules/ngx_eventport_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/perl/nginx.pm src/http/modules/perl/nginx.xs src/http/ngx_http_request.c src/http/ngx_http_variables.c src/os/unix/ngx_atomic.h src/os/unix/ngx_gcc_atomic_ppc.h src/os/unix/ngx_process.c src/os/unix/ngx_process_cycle.c
diffstat 27 files changed, 303 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,22 @@
 
+Changes with nginx 0.5.5                                         24 Dec 2006
+
+    *) 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.
+
+
 Changes with nginx 0.5.4                                         15 Dec 2006
 
     *) Feature: the "perl" directive may be used inside the "limit_except" 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,22 @@
 
+Изменения в nginx 0.5.5                                           24.12.2006
+
+    *) Изменение: ключ -v больше не выводит информацию о компиляторе.
+
+    *) Добавление: ключ -V.
+
+    *) Добавление: директива worker_rlimit_core поддерживает указание 
+       размера в K, M и G.
+
+    *) Исправление: модуль nginx.pm теперь может устанавливаться 
+       непривилегированным пользователем.
+
+    *) Исправление: при использовании методов $r->request_body или 
+       $r->request_body_file мог произойти segmentation fault.
+
+    *) Исправление: ошибок, специфичных для платформы ppc.
+
+
 Изменения в nginx 0.5.4                                           15.12.2006
 
     *) Добавление: директиву perl можно использовать внутри блока 
--- a/auto/cc/name
+++ b/auto/cc/name
@@ -2,7 +2,25 @@
 # Copyright (C) Igor Sysoev
 
 
-echo $ngx_n "checking for C compiler ...$ngx_c"
+if [ "$NGX_PLATFORM" != win32 ]; then
+
+    ngx_feature="C compiler"
+    ngx_feature_name=
+    ngx_feature_run=yes
+    ngx_feature_incs=
+    ngx_feature_path=
+    ngx_feature_libs=
+    ngx_feature_test=
+    . auto/feature
+
+    if [ $ngx_found = no ]; then
+        echo
+        echo $0: error: C compiler $CC is not found
+        echo
+        exit 1
+    fi
+
+fi
 
 
 if [ "$CC" = cl ]; then
@@ -11,51 +29,50 @@ if [ "$CC" = cl ]; then
         >/dev/null 2>&1`; then
 
         NGX_CC_NAME=msvc7
-        echo " Microsoft Visual C++ 7 compiler"
+        echo " + using Microsoft Visual C++ 7 compiler"
 
     else
         NGX_CC_NAME=msvc
-        echo " Microsoft Visual C++ compiler"
+        echo " + using Microsoft Visual C++ compiler"
     fi
 
 else
 if [ "$CC" = wcl386 ]; then
     NGX_CC_NAME=owc
-    echo " Open Watcom C compiler"
+    echo " + using Open Watcom C compiler"
 
 else
 if [ "$CC" = bcc32 ]; then
     NGX_CC_NAME=bcc
-    echo " Borland C++ compiler"
+    echo " + using Borland C++ compiler"
 
 else
 if `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then
     NGX_CC_NAME=gcc
-    echo " GNU C compiler"
+    echo " + using GNU C compiler"
 
 else
 if `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then
     NGX_CC_NAME=icc
-    echo " Intel C++ compiler"
+    echo " + using Intel C++ compiler"
 
 else
 if `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then
     NGX_CC_NAME=sunc
-    echo " Sun C compiler"
+    echo " + using Sun C compiler"
 
 else
 if `$CC -V 2>&1 | grep '^Compaq C' >/dev/null 2>&1`; then
     NGX_CC_NAME=ccc
-    echo " Compaq C compiler"
+    echo " + using Compaq C compiler"
 
 else
 if `$CC -V 2>&1 | grep '^aCC: ' >/dev/null 2>&1`; then
     NGX_CC_NAME=acc
-    echo " HP aC++ compiler"
+    echo " + using HP aC++ compiler"
 
 else
     NGX_CC_NAME=unknown
-    echo " unknown"
 
 fi # acc
 fi # ccc
--- a/auto/feature
+++ b/auto/feature
@@ -41,7 +41,7 @@ ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLA
 
 ngx_feature_inc_path=
 
-eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
+eval "/bin/sh -c \"$ngx_test\" >> $NGX_AUTOCONF_ERR 2>&1"
 
 
 if [ -x $NGX_AUTOTEST ]; then
--- a/auto/lib/perl/conf
+++ b/auto/lib/perl/conf
@@ -47,6 +47,7 @@ if test -n "$NGX_PERL_VER"; then
     if test -n "$NGX_PERL_MODULES"; then
         have=NGX_PERL_MODULES value="(u_char *) \"$NGX_PERL_MODULES\""
         . auto/define
+        NGX_PERL_MODULES_MAN=$NGX_PERL_MODULES/man3
     fi
 
 else
--- a/auto/lib/perl/make
+++ b/auto/lib/perl/make
@@ -30,6 +30,7 @@ cat << END                              
 			NGX_PCRE=$PCRE					\
 			NGX_OBJS=$NGX_OBJS				\
 		$NGX_PERL Makefile.PL					\
-			LIB=$NGX_PERL_MODULES
+			LIB=$NGX_PERL_MODULES				\
+			INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN
 
 END
--- a/auto/os/conf
+++ b/auto/os/conf
@@ -42,6 +42,16 @@ case "$NGX_PLATFORM" in
         CORE_INCS="$UNIX_INCS"
         CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
         CORE_SRCS="$UNIX_SRCS"
+
+        ngx_feature="atomic(3)"
+        ngx_feature_name=NGX_DARWIN_ATOMIC
+        ngx_feature_run=no
+        ngx_feature_incs="#include <libkern/OSAtomic.h>"
+        ngx_feature_path=
+        ngx_feature_libs=
+        ngx_feature_test="int32_t  lock, n;
+                          n = OSAtomicCompareAndSwap32Barrier(0, 1, lock)"
+        . auto/feature
     ;;
 
     HP-UX:*)
--- a/configure
+++ b/configure
@@ -3,6 +3,8 @@
 # Copyright (C) Igor Sysoev
 
 
+NGX_CONFIGURE=`echo $@ | sed 's/"/\\\\"/g'`
+
 . auto/options
 . auto/init
 . auto/sources
@@ -10,9 +12,10 @@
 test -d $NGX_OBJS || mkdir $NGX_OBJS
 
 echo > $NGX_AUTO_HEADERS_H
-echo > $NGX_AUTO_CONFIG_H
 echo > $NGX_AUTOCONF_ERR
 
+echo "#define NGX_CONFIGURE \"$NGX_CONFIGURE\"" > $NGX_AUTO_CONFIG_H
+
 
 if [ $NGX_DEBUG = YES ]; then
     have=NGX_DEBUG . auto/have
@@ -32,14 +35,15 @@ if test -z "$NGX_PLATFORM"; then
 
 else
     echo "building for $NGX_PLATFORM"
+    NGX_SYSTEM=$NGX_PLATFORM
 fi
 
+. auto/cc/conf
 
 if [ "$NGX_PLATFORM" != win32 ]; then
     . auto/headers
 fi
 
-. auto/cc/conf
 . auto/os/conf
 
 if [ "$NGX_PLATFORM" != win32 ]; then
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -109,7 +109,7 @@ static ngx_command_t  ngx_core_commands[
 
     { ngx_string("worker_rlimit_core"),
       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_num_slot,
+      ngx_conf_set_size_slot,
       0,
       offsetof(ngx_core_conf_t, rlimit_core),
       NULL },
@@ -176,6 +176,7 @@ ngx_module_t  ngx_core_module = {
 ngx_uint_t  ngx_max_module;
 
 static ngx_uint_t  ngx_show_version;
+static ngx_uint_t  ngx_show_configure;
 
 static char  *ngx_null_environ = NULL;
 
@@ -235,10 +236,22 @@ main(int argc, char *const *argv)
         ngx_write_fd(ngx_stderr_fileno, "nginx version: " NGINX_VER CRLF,
                      sizeof("nginx version: " NGINX_VER CRLF) - 1);
 
+        if (ngx_show_configure) {
 #ifdef NGX_COMPILER
-        ngx_write_fd(ngx_stderr_fileno, "built by " NGX_COMPILER CRLF,
-                     sizeof("built by " NGX_COMPILER CRLF) - 1);
+            ngx_write_fd(ngx_stderr_fileno, "built by " NGX_COMPILER CRLF,
+                         sizeof("built by " NGX_COMPILER CRLF) - 1);
 #endif
+
+#ifndef __WATCOMC__
+
+            /* OpenWatcomC could not build the long NGX_CONFIGURE string */
+
+            ngx_write_fd(ngx_stderr_fileno,
+                        "configure arguments: " NGX_CONFIGURE CRLF,
+                        sizeof("configure arguments :" NGX_CONFIGURE CRLF) - 1);
+#endif
+        }
+
         if (!ngx_test_config) {
             return 0;
         }
@@ -252,6 +265,12 @@ main(int argc, char *const *argv)
         return 1;
     }
 
+    /* ngx_crc32_init() requires ngx_cacheline_size set in ngx_os_init() */
+
+    if (ngx_crc32_init() != NGX_OK) {
+        return 1;
+    }
+
     if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
         return 1;
     }
@@ -283,10 +302,6 @@ main(int argc, char *const *argv)
 
     ngx_os_status(cycle->log);
 
-    if (ngx_crc32_init(cycle->pool) != NGX_OK) {
-        return 1;
-    }
-
     ngx_cycle = cycle;
 
     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
@@ -496,6 +511,11 @@ ngx_getopt(ngx_cycle_t *cycle, int argc,
             ngx_show_version = 1;
             break;
 
+        case 'V':
+            ngx_show_version = 1;
+            ngx_show_configure = 1;
+            break;
+
         case 't':
             ngx_test_config = 1;
             break;
@@ -600,7 +620,7 @@ ngx_core_module_create_conf(ngx_cycle_t 
     ccf->debug_points = NGX_CONF_UNSET;
 
     ccf->rlimit_nofile = NGX_CONF_UNSET;
-    ccf->rlimit_core = NGX_CONF_UNSET;
+    ccf->rlimit_core = NGX_CONF_UNSET_SIZE;
     ccf->rlimit_sigpending = NGX_CONF_UNSET;
 
     ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT;
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VERSION      "0.5.4"
+#define NGINX_VERSION      "0.5.5"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_crc32.c
+++ b/src/core/ngx_crc32.c
@@ -102,7 +102,7 @@ uint32_t *ngx_crc32_table_short = ngx_cr
 
 
 ngx_int_t
-ngx_crc32_init(ngx_pool_t *pool)
+ngx_crc32_init(void)
 {
     void  *p;
 
@@ -113,7 +113,7 @@ ngx_crc32_init(ngx_pool_t *pool)
         return NGX_OK;
     }
 
-    p = ngx_palloc(pool, 16 * sizeof(uint32_t) + ngx_cacheline_size);
+    p = ngx_alloc(16 * sizeof(uint32_t) + ngx_cacheline_size, ngx_cycle->log);
     if (p == NULL) {
         return NGX_ERROR;
     }
--- a/src/core/ngx_crc32.h
+++ b/src/core/ngx_crc32.h
@@ -49,7 +49,7 @@ ngx_crc32_long(u_char *p, size_t len)
 }
 
 
-ngx_int_t ngx_crc32_init(ngx_pool_t *pool);
+ngx_int_t ngx_crc32_init(void);
 
 
 #endif /* _NGX_CRC32_H_INCLUDED_ */
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -759,7 +759,7 @@ ngx_create_pidfile(ngx_str_t *name, ngx_
     size_t            len;
     ngx_uint_t        trunc;
     ngx_file_t        file;
-    u_char            pid[NGX_INT64_LEN];
+    u_char            pid[NGX_INT64_LEN + 2];
 
     ngx_memzero(&file, sizeof(ngx_file_t));
 
@@ -778,7 +778,7 @@ ngx_create_pidfile(ngx_str_t *name, ngx_
     }
 
     if (!ngx_test_config) {
-        len = ngx_sprintf(pid, "%P%N", ngx_pid) - pid;
+        len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
 
         if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
             return NGX_ERROR;
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -68,8 +68,8 @@ typedef struct {
      ngx_int_t                debug_points;
 
      ngx_int_t                rlimit_nofile;
-     ngx_int_t                rlimit_core;
      ngx_int_t                rlimit_sigpending;
+     size_t                   rlimit_core;
 
      int                      priority;
 
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -92,13 +92,14 @@ ngx_log_error_core(ngx_uint_t level, ngx
 
     p = errstr + ngx_cached_err_log_time.len;
 
-    p = ngx_sprintf(p, " [%s] ", err_levels[level]);
+    p = ngx_snprintf(p, last - p, " [%s] ", err_levels[level]);
 
     /* pid#tid */
-    p = ngx_sprintf(p, "%P#" NGX_TID_T_FMT ": ", ngx_log_pid, ngx_log_tid);
+    p = ngx_snprintf(p, last - p, "%P#" NGX_TID_T_FMT ": ",
+                    ngx_log_pid, ngx_log_tid);
 
     if (log->connection) {
-        p = ngx_sprintf(p, "*%uA ", log->connection);
+        p = ngx_snprintf(p, last - p, "*%uA ", log->connection);
     }
 
 #if (NGX_HAVE_VARIADIC_MACROS)
--- a/src/core/ngx_palloc.c
+++ b/src/core/ngx_palloc.c
@@ -85,14 +85,17 @@ void *
 ngx_palloc(ngx_pool_t *pool, size_t size)
 {
     u_char            *m;
-    ngx_pool_t        *p, *n;
+    ngx_pool_t        *p, *n, *current;
     ngx_pool_large_t  *large;
 
     if (size <= (size_t) NGX_MAX_ALLOC_FROM_POOL
         && size <= (size_t) (pool->end - (u_char *) pool)
                    - (size_t) ngx_align_ptr(sizeof(ngx_pool_t), NGX_ALIGNMENT))
     {
-        for (p = pool->current; /* void */ ; p = p->next) {
+        p = pool->current;
+        current = p;
+
+        for ( ;; ) {
 
             if (size < sizeof(int) || (size & 1)) {
                 m = p->last;
@@ -108,12 +111,15 @@ ngx_palloc(ngx_pool_t *pool, size_t size
             }
 
             if ((size_t) (p->end - m) < NGX_ALIGNMENT) {
-                pool->current = p->next;
+                current = p->next;
             }
 
             if (p->next == NULL) {
                 break;
             }
+
+            p = p->next;
+            pool->current = current;
         }
 
         /* allocate a new pool block */
@@ -123,9 +129,7 @@ ngx_palloc(ngx_pool_t *pool, size_t size
             return NULL;
         }
 
-        if (pool->current == NULL) {
-            pool->current = n;
-        }
+        pool->current = current ? current : n;
 
         p->next = n;
         m = ngx_align_ptr(n->last, NGX_ALIGNMENT);
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -19,7 +19,7 @@
 
 #define NGX_TIME_SLOTS   64
 
-static ngx_uint_t        slot = NGX_TIME_SLOTS;
+static ngx_uint_t        slot;
 static ngx_atomic_t      ngx_time_lock;
 
 volatile ngx_msec_t      ngx_current_msec;
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -468,7 +468,7 @@ ngx_eventport_process_events(ngx_cycle_t
 
             if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
                 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                              "prot_getn() error fd:%d ev:%04Xd",
+                              "port_getn() error fd:%d ev:%04Xd",
                               event_list[i].portev_object, revents);
             }
 
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -847,7 +847,7 @@ ngx_http_proxy_process_status_line(ngx_h
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http proxy status %ui \"%V\"",
-                   u->headers_in.status, &u->headers_in.status_line);
+                   u->headers_in.status_n, &u->headers_in.status_line);
 
     u->process_header = ngx_http_proxy_process_header;
 
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '0.5.4';
+our $VERSION = '0.5.5';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -387,7 +387,10 @@ request_body(r)
 
     ngx_http_perl_set_request(r);
 
-    if (r->request_body->temp_file || r->request_body->bufs == NULL) {
+    if (r->request_body == NULL
+        || r->request_body->temp_file
+        || r->request_body->bufs == NULL)
+    {
         XSRETURN_UNDEF;
     }
 
@@ -411,7 +414,7 @@ request_body_file(r)
 
     ngx_http_perl_set_request(r);
 
-    if (r->request_body->temp_file == NULL) {
+    if (r->request_body == NULL || r->request_body->temp_file == NULL) {
         XSRETURN_UNDEF;
     }
 
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1104,7 +1104,9 @@ ngx_http_alloc_large_header_buffer(ngx_h
 
         if (r->host_start) {
             r->host_start = new + (r->host_start - old);
-            r->host_end = new + (r->host_end - old);
+            if (r->host_end) {
+                r->host_end = new + (r->host_end - old);
+            }
         }
 
         if (r->port_start) {
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -678,9 +678,13 @@ ngx_http_variable_host(ngx_http_request_
             v->data = r->server_name.data;
         }
 
-    } else {
+    } else if (r->host_end) {
         v->len = r->host_end - r->host_start;
         v->data = r->host_start;
+
+    } else {
+        v->not_found = 1;
+        return NGX_OK;
     }
 
     v->valid = 1;
--- a/src/os/unix/ngx_atomic.h
+++ b/src/os/unix/ngx_atomic.h
@@ -12,6 +12,62 @@
 #include <ngx_core.h>
 
 
+#if (NGX_DARWIN_ATOMIC)
+
+/*
+ * use Darwin 8 atomic(3) and barrier(3) operations
+ * optimized at run-time for UP and SMP
+ */
+
+#include <libkern/OSAtomic.h>
+
+/* "bool" conflicts with perl's CORE/handy.h
+ * "true" and "false" conflict with nginx, and of course we can rename them,
+ * but we need to undef "bool" anyway
+ */
+#undef bool
+#undef true
+#undef false
+
+
+#define NGX_HAVE_ATOMIC_OPS  1
+
+#if (NGX_PTR_SIZE == 8)
+
+typedef int64_t                     ngx_atomic_int_t;
+typedef uint64_t                    ngx_atomic_uint_t;
+#define NGX_ATOMIC_T_LEN            sizeof("-9223372036854775808") - 1
+
+#define ngx_atomic_cmp_set(lock, old, new)                                    \
+    OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)
+
+#define ngx_atomic_fetch_add(value, add)                                      \
+    (OSAtomicAdd64(add, (int64_t *) value) - add)
+
+#else
+
+typedef int32_t                     ngx_atomic_int_t;
+typedef uint32_t                    ngx_atomic_uint_t;
+#define NGX_ATOMIC_T_LEN            sizeof("-2147483648") - 1
+
+#define ngx_atomic_cmp_set(lock, old, new)                                    \
+    OSAtomicCompareAndSwap32Barrier(old, new, (int32_t *) lock)
+
+#define ngx_atomic_fetch_add(value, add)                                      \
+    (OSAtomicAdd32(add, (int32_t *) value) - add)
+
+#endif
+
+#define ngx_memory_barrier()        OSMemoryBarrier()
+
+#define ngx_cpu_pause()
+
+typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
+
+
+#else /* !(NGX_DARWIN) */
+
+
 #if ( __i386__ || __i386 )
 
 typedef int32_t                     ngx_atomic_int_t;
@@ -141,6 +197,8 @@ typedef volatile ngx_atomic_uint_t  ngx_
 
 #endif
 
+#endif
+
 
 #if !(NGX_HAVE_ATOMIC_OPS)
 
@@ -181,6 +239,7 @@ ngx_atomic_fetch_add(ngx_atomic_t *value
 
 #endif
 
+
 void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);
 
 #define ngx_trylock(lock)  (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
--- 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()
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -444,10 +444,14 @@ ngx_process_get_status(void)
                 return;
             }
 
-#if (NGX_SOLARIS)
+#if (NGX_SOLARIS || NGX_FREEBSD)
 
             /*
              * Solaris always calls the signal handler for each exited process
+             * despite waitpid() may be already called for this process.
+             *
+             * When several processes exit at the same time FreeBSD may
+             * erroneously call the signal handler for exited process
              * despite waitpid() may be already called for this process
              */
 
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -787,7 +787,7 @@ ngx_worker_process_init(ngx_cycle_t *cyc
             }
         }
 
-        if (ccf->rlimit_core != NGX_CONF_UNSET) {
+        if (ccf->rlimit_core != NGX_CONF_UNSET_SIZE) {
             rlmt.rlim_cur = (rlim_t) ccf->rlimit_core;
             rlmt.rlim_max = (rlim_t) ccf->rlimit_core;