热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

(ARMv7)自旋锁、读写锁、顺序锁代码追踪

自选锁staticinlinevoidspin_lock(spinlock_t*lock){raw_spin_lock(&lock->rl
//自选锁
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

 


推荐阅读
  • 普通树(每个节点可以有任意数量的子节点)级序遍历 ... [详细]
  • Android 自定义 RecycleView 左滑上下分层示例代码
    为了满足项目需求,需要在多个场景中实现左滑删除功能,并且后续可能在列表项中增加其他功能。虽然网络上有很多左滑删除的示例,但大多数封装不够完善。因此,我们尝试自己封装一个更加灵活和通用的解决方案。 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • 本文探讨了如何通过编程手段在Linux系统中禁用硬件预取功能。基于Intel® Core™微架构的应用性能优化需求,文章详细介绍了相关配置方法和代码实现,旨在帮助开发人员有效控制硬件预取行为,提升应用程序的运行效率。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • 三角测量计算三维坐标的代码_双目三维重建——层次化重建思考
    双目三维重建——层次化重建思考FesianXu2020.7.22atANTFINANCIALintern前言本文是笔者阅读[1]第10章内容的笔记,本文从宏观的角度阐 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • 本文对比了杜甫《喜晴》的两种英文翻译版本:a. Pleased with Sunny Weather 和 b. Rejoicing in Clearing Weather。a 版由 alexcwlin 翻译并经 Adam Lam 编辑,b 版则由哈佛大学的宇文所安教授 (Prof. Stephen Owen) 翻译。 ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
author-avatar
rvu2352314
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有