==============================================

本文系本站原创,欢迎转载!转载请注明出处:http://www.cnblogs.com/gdt-a20

==============================================

看一下spinlock,以arm为例,

一、先看结构:

include/linux/spinlock_types.h

 1 typedef struct spinlock { 2     union { 3         struct raw_spinlock rlock; 4  5 #ifdef CONFIG_DEBUG_LOCK_ALLOC        //忽略debug部分 6 # define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map)) 7         struct { 8             u8 __padding[LOCK_PADSIZE]; 9             struct lockdep_map dep_map;10         };11 #endif12     };13 } spinlock_t;

 1 typedef struct raw_spinlock { 2     arch_spinlock_t raw_lock;             //arch相关结构 3 #ifdef CONFIG_GENERIC_LOCKBREAK 4     unsigned int break_lock; 5 #endif 6 #ifdef CONFIG_DEBUG_SPINLOCK 7     unsigned int magic, owner_cpu; 8     void *owner; 9 #endif10 #ifdef CONFIG_DEBUG_LOCK_ALLOC11     struct lockdep_map dep_map;12 #endif13 } raw_spinlock_t;

arch/arm/include/asm/spinlock_types.h

1 typedef struct {2     volatile unsigned int lock;3 } arch_spinlock_t;

二、spinlock操作

1.加锁 include/linux/spinlock.h

1 static inline void spin_lock(spinlock_t *lock)2 {3     raw_spin_lock(&lock->rlock);4 }

1 #define raw_spin_lock(lock)    _raw_spin_lock(lock)

kernel/spinlock.c

1 void __lockfunc _raw_spin_lock(raw_spinlock_t *lock)2 {3     __raw_spin_lock(lock);4 }

include/linux/spinlock_api_smp.h

1 static inline void __raw_spin_lock(raw_spinlock_t *lock)2 {3     preempt_disable();                       //抢占点                          4     spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);5     LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);6 }

include/linux/preempt.h

 1 #ifdef CONFIG_PREEMPT_COUNT               //支持才起作用,否则为空 2  3 #define preempt_disable() \ 4 do { \ 5     inc_preempt_count(); \               //增加抢占计数 6     barrier(); \                         // 7 } while (0) 8  9 #define preempt_enable_no_resched() \10 do { \11     barrier(); \12     dec_preempt_count(); \13 } while (0)14 15 #define preempt_enable() \16 do { \17     preempt_enable_no_resched(); \18     barrier(); \19     preempt_check_resched(); \20 } while (0)21 22 /* For debugging and tracer internals only! */23 #define add_preempt_count_notrace(val)            \24     do { preempt_count() += (val); } while (0)25 #define sub_preempt_count_notrace(val)            \26     do { preempt_count() -= (val); } while (0)27 #define inc_preempt_count_notrace() add_preempt_count_notrace(1)28 #define dec_preempt_count_notrace() sub_preempt_count_notrace(1)29 30 #define preempt_disable_notrace() \31 do { \32     inc_preempt_count_notrace(); \33     barrier(); \34 } while (0)35 36 #define preempt_enable_no_resched_notrace() \37 do { \38     barrier(); \39     dec_preempt_count_notrace(); \40 } while (0)41 42 /* preempt_check_resched is OK to trace */43 #define preempt_enable_notrace() \44 do { \45     preempt_enable_no_resched_notrace(); \46     barrier(); \47     preempt_check_resched(); \48 } while (0)49 50 #else /* !CONFIG_PREEMPT_COUNT */51 52 #define preempt_disable()        do { } while (0)53 #define preempt_enable_no_resched()    do { } while (0)54 #define preempt_enable()        do { } while (0)55 56 #define preempt_disable_notrace()        do { } while (0)57 #define preempt_enable_no_resched_notrace()    do { } while (0)58 #define preempt_enable_notrace()        do { } while (0)59 60 #endif /* CONFIG_PREEMPT_COUNT */

1 #define inc_preempt_count() add_preempt_count(1)

1 # define add_preempt_count(val)    do { preempt_count() += (val); } while (0)

1 #define preempt_count()    (current_thread_info()->preempt_count)

#compiler-gcc.h

1 /* Optimization barrier */2 /* The "volatile" is due to gcc bugs */3 #define barrier() __asm__ __volatile__("": : :"memory")
/*
如果汇编指令修改了内存,但是GCC 本身却察觉不到,因为在输出部分没有描述,
此时就需要在修改描述部分增加"memory",告诉GCC 内存已经被修改,GCC 得知这个信息后,就会在这段指令之前,
插入必要的指令将前面因为优化Cache 到寄存器中的变量值先写回内存,如果以后又要使用这些变量再重新读取。
*/

#about LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);

include/linux/lockdep.h

1 #define LOCK_CONTENDED(_lock, try, lock) \2     lock(_lock)

#include/linux/spinlock.h

1 static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)2 {3     __acquire(lock);4     arch_spin_lock(&lock->raw_lock);5 }

#include/linux/compiler.h

1 # define __acquire(x)    __context__(x,1)  
//it's designed to test that the entry and exit contexts match, 
//and that no path through a function is ever entered with conflicting contexts. 

#about arch_spin_lock in arch/arm/include/asm

 1 static inline void arch_spin_lock(arch_spinlock_t *lock) 2 { 3     unsigned long tmp; 4  5     __asm__ __volatile__(               //循环测试 6 "1:    ldrex    %0, [%1]\n" 7 "    teq    %0, #0\n" 8     WFE("ne") 9 "    strexeq    %0, %2, [%1]\n"10 "    teqeq    %0, #0\n"11 "    bne    1b"12     : "=&r" (tmp)13     : "r" (&lock->lock), "r" (1)14     : "cc");15 16     smp_mb();17 }

1 #ifndef CONFIG_SMP2 #define smp_mb()    barrier()3 #define smp_rmb()    barrier()4 #define smp_wmb()    barrier()5 #else6 #define smp_mb()    dmb()7 #define smp_rmb()    dmb()8 #define smp_wmb()    dmb()9 #endif

2.顺便看下#define raw_spin_lock_irq(lock)  _raw_spin_lock_irq(lock)

最终会有如下操作

1 static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)2 {3     local_irq_disable();     //disable irq4     preempt_disable();5     spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);6     LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);7 }

Thanks

转载于:https://www.cnblogs.com/gdt-a20/archive/2012/01/14/2322298.html

spinlock导读相关推荐

  1. linux kernel的spinlock代码导读和分析

    文章目录 一.代码阅读分析 0.spin lock调用流程图 1.再kernel中调用spi_lock()或spin_unlock函数 2.调用raw_spin_lock()和raw_spin_unl ...

  2. settimeout需要清除吗_【期刊导读】新证据:HBsAg水平极低的非活动性HBsAg携带者经聚乙二醇干扰素治疗24周, HBsAg清除率高达83.3%...

    编者按:目前指南并没有推荐非活动性HBsAg携带者(IHC)进行抗病毒治疗,但在长期随访中发现有IHC仍存在一定的复发和肝癌风险,而获得HBsAg清除会将慢乙肝患者肝癌风险降至最低.因此许多IHC会有 ...

  3. 《C陷阱与缺陷》一导读

    前 言 C陷阱与缺陷 对于经验丰富的行家而言,得心应手的工具在初学时的困难程度往往要超过那些容易上手的工具.刚刚接触飞机驾驶的学员,初航时总是谨小慎微,只敢沿着海岸线来回飞行,等他们稍有经验就会明白这 ...

  4. 分享Silverlight/WPF/Windows Phone一周学习导读(1月17日-1月23日)

    上周微软Silverlight团队发布"微软发布Silverlight Native Extensions 1.0 - 扩展OOB应用功能",对于Silverlight开发人员而言 ...

  5. 关于计算机视觉的那些论文 | CCF推荐论文导读

    目 录 1 Quality Evaluation for Image Retargeting With Instance Semantics 2 PFAN++: Bi-Directional Imag ...

  6. 转:经典论文翻译导读之《Google File System》

    首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源 - 导航条 -首页所有文章资讯Web架构基础技术书籍教程Java小组工具资源 经典论文翻译导读之<Google ...

  7. 分享Silverlight/WPF/Windows Phone一周学习导读(10月1日-10月15日)

    分享Silverlight/WPF/Windows Phone一周学习导读(10月1日-10月15日) 本周Silverlight学习资源更新: [Silverlight入门系列]ListboxIte ...

  8. 分享Silverlight/WPF/Windows Phone一周学习导读(10月30日-11月6日)

    分享Silverlight/WPF/Windows Phone一周学习导读(10月30日-11月6日) 本周Silverlight学习资源更新 Silverlight 定位 niejunhua [学习 ...

  9. .net framework 4中SpinLock和lock的区别

    SpinLock,自旋锁.尝试获取该锁的线程持续不断的check是否可以获得.此时线程仍然是激活状态,只是在空转,浪费cpu而已.但是spinlock避免了线程调度和上下文切换,如果锁的时间极短的话, ...

最新文章

  1. 扇贝python课程打卡_Python爬虫:获取扇贝打卡信息
  2. need study
  3. Kfold交叉验证心得
  4. python-ldap “expected a string in the list”
  5. Linux——POSIX有名信号量
  6. SpringBoot整合Dubbo+Zookeeper进行分布式搭建系统
  7. Node.js 入门详解(四)
  8. 在matlab中function,Matlab中function函数使用操作方法
  9. linux 安卓svn,linux安装svn
  10. FTP服务器:Rumpus for Mac
  11. Windows上的Spark环境搭建后,运行时报错的问题
  12. android adb.exe端口占用
  13. 学硬件设计,需要看哪些书籍?
  14. 西刺代理python_手把手教你使用Python爬取西刺代理数据(下篇)
  15. 计算机中的工作流程,计算机工作流程
  16. 人脸识别,结构光名词记录
  17. STM32 CubeIDE 断点失效的解决方法
  18. 36氪专访融云CEO董晗:8年企服,6年出海,现计划成为「沙特最大科技企业」
  19. 你需要这样一个Ros软路由—— 路由器+外网+一号通ip线路=动态ip的WiFi信号
  20. 最新macOS Big Sur11.1新功能介绍

热门文章

  1. Redis--Windos下的安装和使用
  2. php html 目录列表,PHP获取文件目录列表
  3. 【java】httpclient 链接偶尔会 Read timed out
  4. 【elasticsearch】 Regexes are disabled. Set [script.painless.regex.enabled] to [true]
  5. 60-400-040-使用-binlog-MySQL BinLog入门
  6. 【elasticsearch】elasticsearch 生命周期 resourceAlreadyExistsException
  7. IDEA多Module的Language Level的问题
  8. hadoop的Avro数据序列化系统
  9. StringBuffer,StringBuilder区别是啥
  10. SpringBoot + SpringBatch + Quartz整合定时批量任务