[私]-optee的同步方法
生活随笔
收集整理的這篇文章主要介紹了
[私]-optee的同步方法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
同步機制
- 1、spin-lock
- 2、mutex
- 3、condvar
- 4、optee的disable irq/enable irq操作
★★★ 友情鏈接 : 個人博客導讀首頁—點擊此處 ★★★
optee的同步方法有三種:spin-lock, mutex, and condvar
1、spin-lock
在使用cpu_spin_lock之前,需先關閉foreign interrupt,如果不關閉則會assert
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(); }aarch32
(core/arch/arm/kernel/spin_lock_a32.S) /* void __cpu_spin_lock(unsigned int *lock) */ FUNC __cpu_spin_lock , : UNWIND( .fnstart)mov r2, #SPINLOCK_LOCK 1:ldrex r1, [r0]cmp r1, #SPINLOCK_UNLOCKwfenestrexeq r1, r2, [r0]cmpeq r1, #0bne 1bdmbbx lr UNWIND( .fnend) END_FUNC __cpu_spin_lock/* void __cpu_spin_unlock(unsigned int *lock) */ FUNC __cpu_spin_unlock , : UNWIND( .fnstart)dmbmov r1, #SPINLOCK_UNLOCKstr r1, [r0]dsbsevbx lr UNWIND( .fnend) END_FUNC __cpu_spin_unlockaarch64
(core/arch/arm/kernel/spin_lock_a64.S) /* void __cpu_spin_lock(unsigned int *lock); */ FUNC __cpu_spin_lock , :mov w2, #SPINLOCK_LOCKsevl l1: wfe l2: ldaxr w1, [x0]cbnz w1, l1stxr w1, w2, [x0]cbnz w1, l2ret END_FUNC __cpu_spin_lock/* void __cpu_spin_unlock(unsigned int *lock); */ FUNC __cpu_spin_unlock , :stlr wzr, [x0]ret END_FUNC __cpu_spin_unlock2、mutex
void mutex_unlock(struct mutex *m) {__mutex_unlock(m, NULL, -1); }void mutex_lock(struct mutex *m) {__mutex_lock(m, NULL, -1); }static void __mutex_lock(struct mutex *m, const char *fname, int lineno) {assert_have_no_spinlock();assert(thread_get_id_may_fail() != -1);assert(thread_is_in_normal_mode());while (true) {uint32_t old_itr_status;bool can_lock;struct wait_queue_elem wqe;int owner = MUTEX_OWNER_ID_NONE;/** If the mutex is locked we need to initialize the wqe* before releasing the spinlock to guarantee that we don't* miss the wakeup from mutex_unlock().** If the mutex is unlocked we don't need to use the wqe at* all.*/old_itr_status = cpu_spin_lock_xsave(&m->spin_lock);can_lock = !m->state;if (!can_lock) {wq_wait_init(&m->wq, &wqe, false /* wait_read */);owner = m->owner_id;assert(owner != thread_get_id_may_fail());} else {m->state = -1; /* write locked */thread_add_mutex(m);}cpu_spin_unlock_xrestore(&m->spin_lock, old_itr_status);if (!can_lock) {/** Someone else is holding the lock, wait in normal* world for the lock to become available.*/wq_wait_final(&m->wq, &wqe, m, owner, fname, lineno);} elsereturn;} }static void __mutex_unlock(struct mutex *m, const char *fname, int lineno) {uint32_t old_itr_status;assert_have_no_spinlock();assert(thread_get_id_may_fail() != -1);old_itr_status = cpu_spin_lock_xsave(&m->spin_lock);if (!m->state)panic();thread_rem_mutex(m);m->state = 0;cpu_spin_unlock_xrestore(&m->spin_lock, old_itr_status);wq_wake_next(&m->wq, m, fname, lineno); }3、condvar
condvar_wait()
condvar_signal()
condvar_broadcast()
4、optee的disable irq/enable irq操作
thread_mask_exceptions()
thread_unmask_exceptions()
(1)、先看一個示例
void core_mmu_set_user_map(struct core_mmu_user_map *map) {uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); //相當于linux的local_irq_disable()/** Update the reserved Context ID and TTBR0*/dsb(); /* ARM erratum 754322 */write_contextidr(0);isb();if (map) {write_ttbr0(map->ttbr0);isb();write_contextidr(map->ctxid);isb();} else {write_ttbr0(read_ttbr1());isb();}tlbi_all();/* Restore interrupts */thread_unmask_exceptions(exceptions); //相當于linux的local_irq_enable() } ```c總結
以上是生活随笔為你收集整理的[私]-optee的同步方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: window使用笔记
- 下一篇: UltraEdit-64中文安装