快速业务通道

分析Linux中Spinlock在ARM及X86平台上的实现

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-10

作者:刘洪涛,华清远见嵌入式学院讲师.

本文主要以2.6.22.6内核分析Linux中spinlock在ARM及X86平台上的实现(不同版本的内核实现形式会有一些差异,但原理大致相同).此处默认大家已经熟悉了spinlock的使用,重点解释容易引起迷惑的体系结构相关的实现部分.

一、spin_lock(lock)的实现

/***include/linux/spinlock.h中***/

#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
//如果配置了SMP或配置自旋锁调试功能
# include <linux/spinlock_api_smp.h>
#else //如果是单处理器且不配置自旋锁调试功能
# include <linux/spinlock_api_up.h>
#endif
……
#define spin_lock(lock) _spin_lock(lock)

1、如果是单处理器

/****include/linux/spinlock_api_up.h****/

#define _spin_lock(lock) __LOCK(lock)
#define __LOCK(lock)
do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)

(1)preempt_disable():禁止抢占
(2)__acquire(lock):在include/linux/compiler.h中有定义
#ifdef __CHECKER__
……
# define __acquire(x) __context__(x,1)
# define __release(x) __context__(x,-1)
#else
……
# define __acquires(x)
# define __releases(x)

这是一对用于sparse对代码检测的相互关联的函数定义,第一句表示要增加变量x的计数,增加量为1,第二句则正好相反,这个是用来函数编译的过程中.如果在代码中出现了不平衡的状况,那么在Sparse的检测中就会报警.如果要使用Sparse检测功能就需要安装sparse工具(参考相关安装方法),然后编译内核

Empire CMS,phome.net

#make zImage C=1 (C=1,只检测新编译的文件,C=2是查所有文件)
Sparse会定义__CHECKER__,如果你没有使用sparse工具,__acquire(lock)则定义为空

(3)(void)(lock):通过插入一个变量本身的求值表达式,使编译器不再报警,如:“variable ''lock'' is defined but never used”.这种求值不会影响运行时的速度.

2、如果配置了SMP

/****include/linux/spinlock_api_smp.h中****/

void __lockfunc _spin_lock(spinlock_t *lock) __acquires(lock);

/***kernel/spinlock.c***/

void __lockfunc _spin_lock(spinlock_t *lock)
{
preempt_disable();
//关闭抢占
spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
//自旋锁调试用,在没有定义自旋锁调试的时候是空函数
_raw_spin_lock(lock);
}

/***include/linux/spinlock.h***/

#ifdef CONFIG_DEBUG_SPINLOCK
extern void _raw_spin_lock(spinlock_t *lock);//在lib/spinlock_debug.c中实现
#else //smp情况
# define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock)

3、__raw_spin_lock在ARM处理器上的实现

/******include/asm-arm/spinlock_types.h***/

typedef struct {
volatile unsigned int lock;
} raw_spinlock_t;

#define __RAW_SPIN_LOCK_UNLOCKED { 0 }

/******include/asm-arm/spinlock.h***/

#if __LINUX_ARM_ARCH__ < 6
#error SMP not supported on pre-ARMv6 CPUs //ARMv6后,才有多核ARM处理器
#endif

Empire CMS,phome.net

……
static inline void

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号