Annotation of embedaddon/nginx/src/os/unix/ngx_gcc_atomic_amd64.h, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * Copyright (C) Igor Sysoev
        !             4:  * Copyright (C) Nginx, Inc.
        !             5:  */
        !             6: 
        !             7: 
        !             8: #if (NGX_SMP)
        !             9: #define NGX_SMP_LOCK  "lock;"
        !            10: #else
        !            11: #define NGX_SMP_LOCK
        !            12: #endif
        !            13: 
        !            14: 
        !            15: /*
        !            16:  * "cmpxchgq  r, [m]":
        !            17:  *
        !            18:  *     if (rax == [m]) {
        !            19:  *         zf = 1;
        !            20:  *         [m] = r;
        !            21:  *     } else {
        !            22:  *         zf = 0;
        !            23:  *         rax = [m];
        !            24:  *     }
        !            25:  *
        !            26:  *
        !            27:  * The "r" is any register, %rax (%r0) - %r16.
        !            28:  * The "=a" and "a" are the %rax register.
        !            29:  * Although we can return result in any register, we use "a" because it is
        !            30:  * used in cmpxchgq anyway.  The result is actually in %al but not in $rax,
        !            31:  * however as the code is inlined gcc can test %al as well as %rax.
        !            32:  *
        !            33:  * The "cc" means that flags were changed.
        !            34:  */
        !            35: 
        !            36: static ngx_inline ngx_atomic_uint_t
        !            37: ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
        !            38:     ngx_atomic_uint_t set)
        !            39: {
        !            40:     u_char  res;
        !            41: 
        !            42:     __asm__ volatile (
        !            43: 
        !            44:          NGX_SMP_LOCK
        !            45:     "    cmpxchgq  %3, %1;   "
        !            46:     "    sete      %0;       "
        !            47: 
        !            48:     : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
        !            49: 
        !            50:     return res;
        !            51: }
        !            52: 
        !            53: 
        !            54: /*
        !            55:  * "xaddq  r, [m]":
        !            56:  *
        !            57:  *     temp = [m];
        !            58:  *     [m] += r;
        !            59:  *     r = temp;
        !            60:  *
        !            61:  *
        !            62:  * The "+r" is any register, %rax (%r0) - %r16.
        !            63:  * The "cc" means that flags were changed.
        !            64:  */
        !            65: 
        !            66: static ngx_inline ngx_atomic_int_t
        !            67: ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
        !            68: {
        !            69:     __asm__ volatile (
        !            70: 
        !            71:          NGX_SMP_LOCK
        !            72:     "    xaddq  %0, %1;   "
        !            73: 
        !            74:     : "+r" (add) : "m" (*value) : "cc", "memory");
        !            75: 
        !            76:     return add;
        !            77: }
        !            78: 
        !            79: 
        !            80: #define ngx_memory_barrier()    __asm__ volatile ("" ::: "memory")
        !            81: 
        !            82: #define ngx_cpu_pause()         __asm__ ("pause")

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>