说明:
- Kernel版本:4.14
- ARM64处理器,Contex-A53,双核
- 使用工具:Source Insight 3.5, Visio
1. 概述
吹起并发机制研究的进攻号角了!
作为第一篇文章,应该提纲挈领的介绍下并发。什么是并发,并发就是:你有两个儿子,同时抢一个玩具玩,你一巴掌打在你大儿子手上,小儿子拿到了玩具。并发是指多个执行流访问同一个资源,并发引起竞态。
来张图吧:
图中每一种颜色代表一种竞态情况,主要归结为三类:
- 进程与进程之间:单核上的抢占,多核上的SMP;
- 进程与中断之间:中断又包含了上半部与下半部,中断总是能打断进程的执行流;
- 中断与中断之间:外设的中断可以路由到不同的CPU上,它们之间也可能带来竞态;
目前内核中提供了很多机制来处理并发问题,spinlock就是其中一种。
spinlock,就是大家熟知的自旋锁,它的特点是自旋锁保护的区域不允许睡眠,可以用在中断上下文中。自旋锁获取不到时,CPU会忙等待,并循环测试等待条件。自旋锁一般用于保护很短的临界区。
资料直通车:Linux内核源码技术学习路线+视频教程内核源码
2. spinlock原理分析
2.1spin_lock/spin_unlock
先看一下函数调用流程:
- spin_lock操作中,关闭了抢占,也就是其他进程无法再来抢占当前进程了;
- spin_lock函数中,关键逻辑需要依赖于体系结构的实现,也就是arch_spin_lock函数;
- spin_unlock函数中,关键逻辑需要依赖于体系结构的实现,也就是arch_spin_unlock函数;
直接看ARM64中这个arch_spin_lock/arch_spin_unlock函数的实现吧:
static inline void arch_spin_lock(arch_spinlock_t *lock)
{
unsigned int tmp;
arch_spinlock_t lockval, newval;
asm volatile(
/* Atomically increment the next ticket. */
ARM64_LSE_ATOMIC_INSN(
/* LL/SC */
" prfm pstl1strm, %3\n"
"1: ldaxr %w0, %3\n"
" add %w1, %w0, %w5\n"
" stxr %w2, %w1, %3\n"
" cbnz %w2, 1b\n&