内核并发管理---spin lock
自旋锁最初是为了在smp系统上使用而设计。
#define preempt_disable() \
do { \
inc_preempt_count(); \
barrier(); \
} while (0)
#define sched_preempt_enable_no_resched() \
do { \
barrier(); \
dec_preempt_count(); \
} while (0)
#define preempt_enable_no_resched() sched_preempt_enable_no_resched()
#define preempt_enable() \
do { \
preempt_enable_no_resched(); \
barrier(); \
preempt_check_resched(); \
} while (0)
/* For debugging and tracer internals only! */
#define add_preempt_count_notrace(val) \
do { preempt_count() += (val); } while (0)
#define sub_preempt_count_notrace(val) \
do { preempt_count() -= (val); } while (0)
#define inc_preempt_count_notrace() add_preempt_count_notrace(1)
#define dec_preempt_count_notrace() sub_preempt_count_notrace(1)
#define preempt_disable_notrace() \
do { \
inc_preempt_count_notrace(); \
barrier(); \
} while (0)
do { \
barrier(); \
dec_preempt_count_notrace(); \
} while (0)
/* preempt_check_resched is OK to trace */
#define preempt_enable_notrace() \
do { \
preempt_enable_no_resched_notrace(); \
barrier(); \
preempt_check_resched(); \
} while (0)
#else /* !CONFIG_PREEMPT_COUNT */ //非抢占模式
#define preempt_disable() do { } while (0)
#define sched_preempt_enable_no_resched() do { } while (0)
#define preempt_enable_no_resched() do { } while (0)
#define preempt_enable() do { } while (0)
#define preempt_disable_notrace() do { } while (0)
#define preempt_enable_no_resched_notrace() do { } while (0)
#define preempt_enable_notrace() do { } while (0)
#endif /* CONFIG_PREEMPT_COUNT */
# ifdef CONFIG_PROVE_LOCKING
# define spin_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i)
# define spin_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i)
# else
# define spin_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i)
# define spin_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, NULL, i)
# endif
# define spin_release(l, n, i) lock_release(l, n, i)
#else
# define spin_acquire(l, s, t, i) do { } while (0)
# define spin_release(l, n, i) do { } while (0)
#endif
extern void lock_contended(struct lockdep_map *lock, unsigned long ip);
extern void lock_acquired(struct lockdep_map *lock, unsigned long ip);
#define LOCK_CONTENDED(_lock, try, lock) \
do { \
if (!try(_lock)) { \
lock_contended(&(_lock)->dep_map, _RET_IP_); \
lock(_lock); \
} \
lock_acquired(&(_lock)->dep_map, _RET_IP_); \
} while (0)
#else /* CONFIG_LOCK_STAT */
#define lock_contended(lockdep_map, ip) do {} while (0)
#define lock_acquired(lockdep_map, ip) do {} while (0)
#define LOCK_CONTENDED(_lock, try, lock) \
lock(_lock)
#endif /* CONFIG_LOCK_STAT */
{
raw_spin_lock(&lock->rlock);
}
void __lockfunc _raw_spin_lock(raw_spinlock_t *lock)
{
__raw_spin_lock(lock);
}
EXPORT_SYMBOL(_raw_spin_lock);
#endif
{
preempt_disable();
spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
}
{
debug_spin_lock_before(lock);
if (unlikely(!arch_spin_trylock(&lock->raw_lock))) //当没加自旋锁时,条件判断为假,不会执行下面一句
__spin_lock_debug(lock);
debug_spin_lock_after(lock);
}
{
unsigned long tmp;
__asm__ __volatile__(
" ldrex %0, [%1]\n" //将lock存在tmp中,若没有人占用锁,则tmp=0;若有人占用锁,tmp=1,直接return0
" teq %0, #0\n" //判断tmp=0就执行下面一句,否则不执行
" strexeq %0, %2, [%1]" //将lock=1,即加锁;写成功tmp=0;不成功tmp=1.
: "=&r" (tmp) // ^ ^
: "r" (&lock->lock), "r" (1) // return 1 return 0
: "cc");
if (tmp == 0) {
smp_mb();
return 1;
} else {
return 0;
}
}
{
unsigned long tmp;
__asm__ __volatile__(
"1: ldrex %0, [%1]\n" //
" teq %0, #0\n" //若tmp=0,
WFE("ne")
" strexeq %0, %2, [%1]\n"
" teqeq %0, #0\n"
" bne 1b"
: "=&r" (tmp)
: "r" (&lock->lock), "r" (1)
: "cc");
smp_mb();
}
内核并发管理---spin lock的更多相关文章
- Linux内核同步机制之(四):spin lock【转】
转自:http://www.wowotech.net/kernel_synchronization/spinlock.html 一.前言 在linux kernel的实现中,经常会遇到这样的场景:共享 ...
- Linux内核同步机制之(五):Read Write spin lock【转】
一.为何会有rw spin lock? 在有了强大的spin lock之后,为何还会有rw spin lock呢?无他,仅仅是为了增加内核的并发,从而增加性能而已.spin lock严格的限制只有一个 ...
- Linux内核同步 - Read/Write spin lock
一.为何会有rw spin lock? 在有了强大的spin lock之后,为何还会有rw spin lock呢?无他,仅仅是为了增加内核的并发,从而增加性能而已.spin lock严格的限制只有一个 ...
- Linux内核内存管理
<Linux内核设计与实现>读书笔记(十二)- 内存管理 内核的内存使用不像用户空间那样随意,内核的内存出现错误时也只有靠自己来解决(用户空间的内存错误可以抛给内核来解决). 所有内核 ...
- linx 内核 并发与同步 1
内核并发来源: 1.硬件中断和异常:中断服务程序和被中断的进程可能发生并发访问资源 2.软中断和tasklet,软中断和taklet随时都可能倍调度执行,从而打断当前正在执行 进程的上下文. 3.内核 ...
- .NET组件程序设计之线程、并发管理(二)
.Net组件程序设计之线程.并发管理(二) 2.同步线程 手动同步 监视器 互斥 可等待事件 同步线程 所有的.NET组件都支持在多线程的环境中运行,可以被多个线程并发访问,如果没有线程同步,这样的后 ...
- EBS Concurrent Manager(并发管理器)异常处理[final]
来自:http://blog.itpub.net/35489/viewspace-742191/ 有时候我们在通过 adstpall.sh 关闭应用后,然后再使用adstrtal.sh开启.发现并发 ...
- spin lock的理解
为什么在spin lock保护的代码里面不允许有休眠的操作呢? 因为spin lock不是空实现的前提下(内核没关抢占,或者是SMP打开),spin lock中是关抢占的,如果一个进程A拿到锁,内核抢 ...
- Pthreads并行编程之spin lock与mutex性能对比分析(转)
POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API.线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用 ...
随机推荐
- [Contest20180325]序列
Hogura有一个序列$a$,她希望你帮她维护下面的这些操作. $1\ l\ r\ x$对$l\leq i\leq r$的$a_i$执行$a_i=a_i+x$ $2\ l\ r\ x$对$l\leq ...
- 什么是EPEL 及 Centos上安装EPEL(转)
什么是EPEL 及 Centos上安装EPEL 转自:http://www.unxmail.com/read.php?67 RHEL以及他的衍生发行版如CentOS.Scientific Linux为 ...
- IntelliJ IDEA下Maven控制台出现中文乱码问题解决
Setting->maven->runner: VMoptions: -Dfile.encoding=GB2312 不一定有效,要不断的尝试.
- 开源的库RestSharp轻松消费Restful Service
现在互联网上的服务接口都是Restful的,SOAP的Service已经不是主流..NET/Mono下如何消费Restful Service呢,再也没有了方便的Visual Studio的方便生产代理 ...
- [Lync]lync同步通讯簿
概述 在客户现场部署lync的时候,突然发现新安装的lync客户端,搜索联系人功能无法使用,而将lync客户端安装后,隔一段时间后,又可以查询了,发现可能是数据没有同步的原因. 解决方案 客户端地址簿 ...
- 【InteillJ IDEA】Git的安装+同步项目到GitHub上
需要的工具: 1.InteillJ IDEA 2.Git 3.GitHub帐号 步骤: 1.下载Git 下载地址:https://git-scm.com/downloads 安装完成后 勾选Launc ...
- .Net使用程序发送邮件时的问题
在做项目的时候,不可避免的会用到给用户发送邮件的问题,一开始我用的是qq的smtp服务器,但是会出错,不管账号密码,服务器地址端口等怎么配置都是出错.后百度之,发现可能是qq服务器本身就是禁止这个功能 ...
- Python3环境安装Scrapy爬虫框架过程及常见错误
收录待用,修改转载已取得腾讯云授权 Scrapy安装介绍 Scrapy的安装有多种方式,它支持Python2.7版本及以上或Python3.3版本及以上.下面说明Python3环境下的安装过程. Sc ...
- POJ 3077-Rounders(水题乱搞)
Rounders Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7697 Accepted: 4984 Descript ...
- JAVA加解密 -- 对称加密算法与非对称加密算法
对称加密算法:双方必须约定好算法 DES 数据加密标准:由于不断地被破解 自98年起就已经逐渐放弃使用 AES 目前使用最多的加密方式,官方并未公布加密方式已被破解,替代DES 实现和DES非常接近 ...