view src/os/unix/ngx_gcc_atomic_amd64.h @ 412:b246022ef454 NGINX_0_7_18

nginx 0.7.18 *) Change: the "underscores_in_headers" directive; now nginx does not allows underscores in a client request header line names. *) Feature: the ngx_http_secure_link_module. *) Feature: the "real_ip_header" directive supports any header. *) Feature: the "log_subrequest" directive. *) Feature: the $realpath_root variable. *) Feature: the "http_502" and "http_504" parameters of the "proxy_next_upstream" directive. *) Bugfix: the "http_503" parameter of the "proxy_next_upstream" or "fastcgi_next_upstream" directives did not work. *) Bugfix: nginx might send a "Transfer-Encoding: chunked" heaer line for HEAD requests. *) Bugfix: now accept threshold depends on worker_connections.
author Igor Sysoev <http://sysoev.ru>
date Mon, 13 Oct 2008 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")