seqlock分析

当需要同步的数据比较简单,且是多读少写,且写优先的,情况下

你可以使用 seqlock

seqlock 的底层是用spin实现,所以自然继承了spin的特性
如: 禁止抢占,sleep 等

typedef struct {
 unsigned sequence;
 spinlock_t lock;
} seqlock_t;

序列号初始化为0,即偶数,代表没有上锁

#define seqlock_init(x)     \
 do {      \
  (x)->sequence = 0;   \
  spin_lock_init(&(x)->lock);  \
 } while (0)


写操作,比较简单,只是对序列号++而已,而这个正式精华

(想想为什么不是++  —— 而只是++)

static inline void write_seqlock(seqlock_t *sl)
{
	spin_lock(&sl->lock);
	++sl->sequence;
	smp_wmb();
}

static inline void write_sequnlock(seqlock_t *sl)
{
	smp_wmb();
	sl->sequence++;
	spin_unlock(&sl->lock);
}

 使用例子: 

 write_seqlock(&xtime_lock);
                // 做些写的操作
                // 。。。。。。。
  write_sequnlock(&xtime_lock);


关键是seqlock对数据的读实现及读取方式

static __always_inline unsigned read_seqbegin(const seqlock_t *sl)
{
	unsigned ret;

repeat:
	ret = sl->sequence;
	smp_rmb();
        // 偶数代表锁释放(初始值为0)
        // sequence只要 ++ 就够了
	if (unlikely(ret & 1)) {
		cpu_relax();
		goto repeat;
	}
	return ret;
}

// 加入序列号有改变的话,说明在这段时间里面写操作有可以改变了数据
static __always_inline int read_seqretry(const seqlock_t *sl, unsigned start)
{
	smp_rmb();

	return (sl->sequence != start);
}

 

// 举个栗子
// 参考 /kernel/kernel/hrtimer.c
static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
{
	ktime_t xtim, tomono;
	struct timespec xts, tom;
	unsigned long seq;

        // 两次返回的值不一样则一致循环
        // 比较 sequence
        // 这样的好处是,对于写没有影响
	do {
		seq = read_seqbegin(&xtime_lock);
		xts = __current_kernel_time();
		tom = wall_to_monotonic;
	} while (read_seqretry(&xtime_lock, seq));
       ................
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值