Nginx source code full annotation (11) ngx_spinlock

Source: Internet
Author: User

Nginx is a multi-process mode. A master and multiple workers generally work on multi-core CPUs, so spin locks are required. The definition of the spin lock in nginx is located in ngx_spinlock.c, as follows:

Voidngx_spinlock (ngx_atomic_t * Lock, negative value, ngx_uint_t spin) {# If (ngx_have_atomic_ops) ngx_uint_t I, n; For (;) {// lock is the lock, is an integer // ngx_atomic_cmp_set is platform-related and generally involves inline assembly if (* Lock = 0 & ngx_atomic_cmp_set (lock, 0, value) {return ;} // multi-core if (ngx_ncpu> 1) {// wait and retry policy, see the description below for (n = 1; n <spin; n <= 1) {for (I = 0; I <n; I ++) {ngx_cpu_pause ();} If (* Lock = 0 & ngx _ Atomic_cmp_set (lock, 0, value) {return ;}} ngx_sched_yield () ;}# else # If (ngx_threads) # error ngx_spinlock () or ngx_atomic_cmp_set () are definnot ed! # Endif}

Here, the integer variable lock is used to represent the lock. On the author's machine (Darwin 12.0), it is defined as follows:

typedef volatile ngx_atomic_uint_t  ngx_atomic_t;

Return to the source code analysis of the above spinlock. If ngx_ncpu (indicating the number of CPU cores) exceeds 1, that is, multi-core CPU, you have to wait/retry. For example, if spin is 80, wait for one ngx_cpu_pause () operation for the first time and check whether the lock is available again. Next, wait for 2, 4, 8, 16, 32, and 64 ngx_cpu_pause () operations in each round and try again. In this intermediate process, if the lock is released and can be used, the loop will be aborted, And the spinlock function will return a value. If the Retry is still unsuccessful, run ngx_sched_yield and then repeat the preceding operation.

In addition, the ngx_atomic_cmp_set function is also very valuable. In Darwin 12.0, the macro definition is as follows:

#define ngx_atomic_cmp_set(lock, old, new)                                    OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)

In a friend of mine's Linux environment (I forgot it, But x86), as follows. For inline assembly, refer to the two blog posts on GCC inline assembly in this blog. SMP is a bus lock.

static ngx_inline ngx_atomic_uint_tngx_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    "    cmpxchgl  %3, %1;   "    "    sete      %0;       "    : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");    return res;}

Output here is res, Which is saved in the eax register. The input is * Lock (in memory), old (in eax), and set (r indicates general registers ). In this way, % 0 is res, % 1 is * Lock, % 2 is old, and % 3 is set.

If * Lock and old are equal, then the difference or (cmpxchgl) is 0, ZF is 1, sete sets the res (% 0) value to 1 and returns it. If * Lock and old are not equal, the fire value is non-zero. Therefore, if ZF is non-zero, sete will not execute the action, that is, the res value is 0, that is, the ngx_atomic_cmp_set call fails.

Cmpxchgl affects the ZF (zero flag) flag.

Nginx source code full annotation (11) ngx_spinlock

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.