nginx自旋锁ngx_spinlock分析

以前也看过linux内核自旋锁的实现代码,现在工作主要是应用程序开发,对应用程序开发不是太了解,我喜欢通过看优秀的开源软件学习软件开发,之前对linux kernel感兴趣就是看内核代码,现在工作需要http,数据库,网络编程这方面的只是,我想学习http和网络编程看完nginx我想也差不多了。


void ngx_spinlock函数代码:

void
ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
{

#if (NGX_HAVE_ATOMIC_OPS)

    ngx_uint_t  i, n;

    for ( ;; ) {
        // 没有上锁则上锁,上锁成功则返回  
        if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
            return;
        }

        if (ngx_ncpu > 1) {  //SMP

            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();  // 看具体实现,任务调度或者usleep。
    }

#else

}





最值得研究的在我看来是应该是ngx_atomic_cmp_set函数的实现。下面是这个函数(其实是个宏定义)
的一个实现。
这和linux内核的自旋锁本质是一样的,核心是在锁总线的情况下,原子完成比较和交换操作,也就是mem和newval
的比较和交换操作。如果上锁成功返回值大于O。
    #define LOCK_PREFIX    "lock;"  
    #define __sync_bool_compare_and_swap(mem, oldval, newval) \  
      ({ __typeof (*mem) ret;                             \  
             __asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1;sete %%al; movzbl %%al,%%eax"                \  
                                : "=a" (ret), "=m" (*mem)                  \  
                                : "r" (newval), "m" (*mem), "a" (oldval)\  
                                :"memory");         \  
                                  ret; })  

我用cscope查找 ngx_sched_yield()函数定义,下面是查找结果。我们可以发现这个函数nginx
根据不同情况有三种实现,*nix提供usleep和sched_yield,win32是SwitchToThread()。
win32我不了解,不过看名字就知道什么意思,切换进程。我们说一下*nix的实现。
*** src/os/unix/ngx_process.h:
ngx_sched_yield[71]            #define ngx_sched_yield() sched_yield()
ngx_sched_yield[73]            #define ngx_sched_yield() usleep(1)

*** src/os/win32/ngx_process.h:
ngx_sched_yield[56]            #define ngx_sched_yield() SwitchToThread()
打开ngx_process.h头文件
有下面几行代码。这意思就很清晰了,不多说。
#if (NGX_HAVE_SCHED_YIELD)
#define ngx_sched_yield()  sched_yield()
#else
#define ngx_sched_yield()  usleep(1)
#endif

*nix OS应用层提供的任务调度函数。
#include <sched.h>
sched_yield()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值