内核同步机制API之write_seqcount_begin

write_seqcount_begin 和 write_seqcount_end 一起配合作为写顺序锁
其使用的例程如下:
static void cpuset_change_task_nodemask(struct task_struct *tsk,
					nodemask_t *newmems)
{
	task_lock(tsk);

	local_irq_disable();
	write_seqcount_begin(&tsk->mems_allowed_seq);

	nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems);
	mpol_rebind_task(tsk, newmems);
	tsk->mems_allowed = *newmems;

	write_seqcount_end(&tsk->mems_allowed_seq);
	local_irq_enable();

	task_unlock(tsk);
}

其源码分析如下:
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 write_seqcount_begin(seqcount_t *s)
{
	write_seqcount_begin_nested(s, 0);
}

static inline void write_seqcount_end(seqcount_t *s)
{
	seqcount_release(&s->dep_map, 1, _RET_IP_);
	raw_write_seqcount_end(s);
}
仔细分析这个函数可以知道,在write_seqcount_begin->write_seqcount_begin_nested->raw_write_seqcount_begin 
static inline void raw_write_seqcount_begin(seqcount_t *s)
{
	s->sequence++;
	smp_wmb();
}
在这个函数中会对s->sequence 子加1,这样当read 顺序读的时候,发现这个值是1,
就会等待write_seqcount_end->raw_write_seqcount_end
static inline void raw_write_seqcount_end(seqcount_t *s)
{
	smp_wmb();
	s->sequence++;
}
让s->sequence再子加1,这样这个值就大于等于2了。这里写顺序锁也就操作完成了,read顺序锁就可以正确获得锁了.

你可能感兴趣的:(Linux,源码分析,kernel常用API源码分析)