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

//自选锁
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]
"
"    teq    %0, #0
"
#ifdef CONFIG_CPU_32v6K
"    wfene
"
#endif
"    strexeq    %0, %2, [%1]
"
"    teqeq    %0, #0
"
"    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]
"
"    teq    %0, #0
"
    WFE("ne")
"    strexeq    %0, %2, [%1]
"
"    teq    %0, #0
"
"    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]
"
"    adds    %0, %0, #1
"
"    strexpl    %1, %0, [%2]
"
    WFE("mi")
"    rsbpls    %0, %1, #0
"
"    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
原文地址:https://www.cnblogs.com/zero-jh/p/5073575.html