view src/os/unix/ngx_gcc_atomic_amd64.h @ 384:09b703ae3ba5 NGINX_0_6_36

nginx 0.6.36 *) Change: now the "Invalid argument" error returned by setsockopt(TCP_NODELAY) on Solaris, is ignored. *) Change: now POSTs without "Content-Length" header line are allowed. *) Feature: the "try_files" directive. *) Feature: the --with-pcre option in the configure. *) Feature: the "if_modified_since" directive. *) Feature: the "$cookie_..." variables. *) Feature: the "$arg_..." variables. *) Bugfix: compatibility with Tru64 UNIX. Thanks to Dustin Marquess. *) Bugfix: a "ssl_engine" directive did not use a SSL-accelerator for asymmetric ciphers. Thanks to Marcin Gozdalik. *) Bugfix: in a redirect rewrite directive original arguments were concatenated with new arguments by a "?" rather than an "&"; the bug had appeared in 0.1.18. Thanks to Maxim Dounin. *) Bugfix: nginx could not be built on AIX. *) Bugfix: a double response might be returned if the epoll or rtsig methods are used and a redirect was returned to a request with body. Thanks to Eden Li. *) Bugfix: a segmentation fault might occur in worker process if "resolver" directive was used in SMTP proxy. *) Bugfix: fastcgi_store stored files not always. *) Bugfix: nginx did not process a FastCGI server response, if the server send too many messages to stderr before response.
author Igor Sysoev <http://sysoev.ru>
date Thu, 02 Apr 2009 00:00:00 +0400
parents 052a7b1d40e5
children
line wrap: on
line source


/*
 * Copyright (C) Igor Sysoev
 */


#if (NGX_SMP)
#define NGX_SMP_LOCK  "lock;"
#else
#define NGX_SMP_LOCK
#endif


/*
 * "cmpxchgq  r, [m]":
 *
 *     if (rax == [m]) {
 *         zf = 1;
 *         [m] = r;
 *     } else {
 *         zf = 0;
 *         rax = [m];
 *     }
 *
 *
 * The "r" is any register, %rax (%r0) - %r16.
 * The "=a" and "a" are the %rax register.
 * Although we can return result in any register, we use "a" because it is
 * used in cmpxchgq anyway.  The result is actually in %al but not in $rax,
 * however as the code is inlined gcc can test %al as well as %rax.
 *
 * The "cc" means that flags were changed.
 */

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)
{
    u_char  res;

    __asm__ volatile (

         NGX_SMP_LOCK
    "    cmpxchgq  %3, %1;   "
    "    sete      %0;       "

    : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");

    return res;
}


/*
 * "xaddq  r, [m]":
 *
 *     temp = [m];
 *     [m] += r;
 *     r = temp;
 *
 *
 * The "+r" is any register, %rax (%r0) - %r16.
 * The "cc" means that flags were changed.
 */

static ngx_inline ngx_atomic_int_t
ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
{
    __asm__ volatile (

         NGX_SMP_LOCK
    "    xaddq  %0, %1;   "

    : "+r" (add) : "m" (*value) : "cc", "memory");

    return add;
}


#define ngx_memory_barrier()    __asm__ volatile ("" ::: "memory")

#define ngx_cpu_pause()         __asm__ ("pause")