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顺序锁就可以正确获得锁了.
内核同步机制API之write_seqcount_begin
最新推荐文章于 2023-04-08 17:16:47 发布