optee中spinlock的实现原理详解
快速链接:
.
👉👉👉 个人博客笔记导读目录(全部) 👈👈👈
相关推荐:
optee中mutex的实现方式
说明: 在默认的情况下,本文讲述的是armv8 aarch64体系,optee 3.12.0代码
文章目录
- 1、cpu_spin_lock
- 2、cpu_spin_unlock
- 3、示例-举例说明
透过事务看本质:
spin_lock的时候,如果lock等于1了,则调用wfe指令,让cpu进入低功耗模式; 如果lock不等于1,则lock++
spi_unlock的时候,直接给lock赋0, 并释放语义,产生等类似于ev指令的信号,唤醒正在处于wfe低功耗的cpu。
1、cpu_spin_lock
static inline void cpu_spin_lock(unsigned int *lock) {cpu_spin_lock_no_dldetect(lock); }static inline void cpu_spin_lock_no_dldetect(unsigned int *lock) {assert(thread_foreign_intr_disabled());__cpu_spin_lock(lock);spinlock_count_incr(); }static inline void spinlock_count_incr(void) { }/* void __cpu_spin_lock(unsigned int *lock); */ FUNC __cpu_spin_lock , :mov w2, #SPINLOCK_LOCK --(1)sevl --(2) l1: wfe --(3) l2: ldaxr w1, [x0] --(4)cbnz w1, l1 --(5)stxr w1, w2, [x0] --(6)cbnz w1, l2 --(7)ret --(8) END_FUNC __cpu_spin_lock2、cpu_spin_unlock
static inline void cpu_spin_unlock(unsigned int *lock) {assert(thread_foreign_intr_disabled());__cpu_spin_unlock(lock);spinlock_count_decr(); }static inline void spinlock_count_decr(void) { }/* void __cpu_spin_unlock(unsigned int *lock); */ FUNC __cpu_spin_unlock , :stlr wzr, [x0] --(9)ret --(10) END_FUNC __cpu_spin_unlock3、示例-举例说明
假设有下列代码,进程A和进程B都要访问临界区(代码请参考上面的)
static unsigned int xxx_spinlock;cpu_spin_lock(&xxx_spinlock);// 临界区cpu_spin_unlock(&xxx_spinlock);-
进程A调用cpu_spin_lock, 其执行顺序:
(1)(2)(3)(4)(5)(6)(7)(8), 执行后xxx_spinlock=1,其中步骤(4)是带有语义的独占指令
然后进程A进入临界区 -
进程B调用cpu_spin_lock, 其执行顺序:
(1)(2)(3)(4)(5)(3), 此时wfe让cpu进入低功耗模式 -
进程A执行完临界区后,调用cpu_spin_unlock,
进程A的执行顺序:
(9)(10),步骤(9)给[x0]清0了,即lock=0, 在执行(9)的时候,操作的[x0]地址正是spi_lock时带有语义的独占指令操作的,这里就会释放该独占指令,将会产生一个类似于sev的信号
进程B收到唤醒信号时,进程B的执行顺序:
(5)(6)(7)(8), 进程B也进入了临界区
我们知道spin_lock是锁cpu之间的互斥的,对应一个cpu之间的抢占是无法锁住的。
所以呢,optee在实现spin_lock时,规定了:在调用spin_lock之前,必需disable掉所有中断,spin_unlock在放开中断。这样就不会有抢占的问题了
总结
以上是生活随笔为你收集整理的optee中spinlock的实现原理详解的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: optee_os中静态共享内存的注册
- 下一篇: optee中mutex的实现方式