(ARM v7)自旋锁、读写锁、顺序锁代码追踪
2015-12-24 16:41
537 查看
//自选锁 static inline void spin_lock(spinlock_t *lock) { raw_spin_lock(&lock->rlock); } #define raw_spin_lock(lock) _raw_spin_lock(lock) void __lockfunc _raw_spin_lock(raw_spinlock_t *lock) { __raw_spin_lock(lock); } static inline void __raw_spin_lock(raw_spinlock_t *lock) { preempt_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } #define preempt_disable() \ do { \ inc_preempt_count(); \ barrier(); \ } while (0) #define inc_preempt_count() add_preempt_count(1) # define add_preempt_count(val) do { preempt_count() += (val); } while (0) #define preempt_count() (current_thread_info()->preempt_count) #define barrier() __asm__ __volatile__("": : :"memory") # define spin_acquire(l, s, t, i) do { } while (0) #define LOCK_CONTENDED(_lock, try, lock) \ lock(_lock) static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock) { __acquire(lock); arch_spin_lock(&lock->raw_lock); } static inline void arch_spin_lock(arch_spinlock_t *lock) { unsigned long tmp; __asm__ __volatile__( "1: ldrex %0, [%1]\n" " teq %0, #0\n" #ifdef CONFIG_CPU_32v6K " wfene\n" #endif " strexeq %0, %2, [%1]\n" " teqeq %0, #0\n" " bne 1b" //yuan di xuan zhuan : "=&r" (tmp) : "r" (&lock->lock), "r" (1) : "cc"); smp_mb(); } #define smp_mb() mb() #define smp_rmb() rmb() #define smp_wmb() wmb() #define mb() do { dsb(); outer_sync(); } while (0) #define rmb() dsb() #define wmb() do { dsb(st); outer_sync(); } while (0) #define dma_rmb() dmb(osh) #define dma_wmb() dmb(oshst) #define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory") #define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory") #define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory") //读写锁 #define write_lock(lock) _raw_write_lock(lock) #define _raw_write_lock(lock) __raw_write_lock(lock) static inline void __raw_write_lock(rwlock_t *lock) { preempt_disable(); rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); } # define do_raw_write_lock(rwlock) do {__acquire(lock); arch_write_lock(&(rwlock)->raw_lock); } while (0) static inline void arch_write_lock(arch_rwlock_t *rw) { unsigned long tmp; prefetchw(&rw->lock); __asm__ __volatile__( "1: ldrex %0, [%1]\n" " teq %0, #0\n" WFE("ne") " strexeq %0, %2, [%1]\n" " teq %0, #0\n" " bne 1b" : "=&r" (tmp) : "r" (&rw->lock), "r" (0x80000000) : "cc"); smp_mb(); } #define read_lock(lock) _raw_read_lock(lock) void __lockfunc _raw_read_lock(rwlock_t *lock) { __raw_read_lock(lock); } static inline void __raw_read_lock(rwlock_t *lock) { preempt_disable(); rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); } void do_raw_read_lock(rwlock_t *lock) { RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); arch_read_lock(&lock->raw_lock); } static inline void arch_read_lock(arch_rwlock_t *rw) { unsigned long tmp, tmp2; prefetchw(&rw->lock); __asm__ __volatile__( "1: ldrex %0, [%2]\n" " adds %0, %0, #1\n" " strexpl %1, %0, [%2]\n" WFE("mi") " rsbpls %0, %1, #0\n" " bmi 1b" : "=&r" (tmp), "=&r" (tmp2) : "r" (&rw->lock) : "cc"); smp_mb(); } //顺序锁 static inline void write_seqlock(seqlock_t *sl) { spin_lock(&sl->lock); write_seqcount_begin(&sl->seqcount); } static inline void write_seqcount_begin(seqcount_t *s) { write_seqcount_begin_nested(s, 0); } static inline void write_seqcount_begin_nested(seqcount_t *s, int subclass) { raw_write_seqcount_begin(s); seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_); } static inline void raw_write_seqcount_begin(seqcount_t *s) { s->sequence++; smp_wmb(); } static inline unsigned read_seqbegin(const seqlock_t *sl) { return read_seqcount_begin(&sl->seqcount); } static inline unsigned read_seqcount_begin(const seqcount_t *s) { seqcount_lockdep_reader_access(s); return raw_read_seqcount_begin(s); } # define seqcount_lockdep_reader_access(x) static inline unsigned raw_read_seqcount_begin(const seqcount_t *s) { unsigned ret = __read_seqcount_begin(s); smp_rmb(); return ret; } static inline unsigned __read_seqcount_begin(const seqcount_t *s) { unsigned ret; repeat: ret = ACCESS_ONCE(s->sequence); if (unlikely(ret & 1)) { cpu_relax(); goto repeat; } return ret; } #define cpu_relax() barrier() static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start) { return read_seqcount_retry(&sl->seqcount, start); } static inline int read_seqcount_retry(const seqcount_t *s, unsigned start) { smp_rmb(); return __read_seqcount_retry(s, start); } static inline int __read_seqcount_retry(const seqcount_t *s, unsigned start) { return unlikely(s->sequence != start); }
View Code
相关文章推荐
- JAVA基础(14) JSTL的C标签使用详解
- 关于spring mvc MaxUploadSizeExceededException 死循环解决方
- C/C++之回调函数
- Java的对象与类
- QT生成的exe自动拷贝依赖的dll并打包的方法
- 关于 myeclipse 中 java heap space的解决办法
- Git项目分支创建、同步代码
- <php+mysql>从PHP连接数据库,以及mysqli_connect()不能使用localhost的解答
- java *** 制作圣诞贺卡
- java proxool系统设置
- eclipse中出现ContainerBase.addChild: start: 的解决办法
- java__webService接口
- <Java> 获取当前系统时间
- 关于java支付宝接口的异步通知的问题
- 我写的WEBPY框架的 提供验证码识别的PYTHON 程序
- RxJava 初识
- 我的java学习笔记之常见异常总结-2…
- 我的java学习笔记之杰信商务管理平…
- 我的java学习笔记之项目-2015-12-2…
- 我的java框架学习笔记spring入门及…