linux rculist代码分析

本文详细介绍了Linux内核中RCU(Read-Copy Update)机制下rculist的使用,包括list_next_rcu、list_add_rcu、list_add_tail_rcu、list_del_rcu、list_replace_rcu等操作。这些函数用于在多读一写并发场景下保护链表操作的正确性,确保并发安全。文章通过代码分析解释了RCU如何保证读取线程的完整性,以及相关操作的实现原理。
摘要由CSDN通过智能技术生成

 

此博客写的匆忙并且全为个人见解,错误之处请大家赶快指出。

 

linux内核rcu机制,是在多读线程和一个写线程并发情况下对指针的保户机制,多写并发需要加锁。

常应用于链表的数据操作中。

linux内核rculist.h是对链表带rcu保护机制操作函数的实现和封装,位于kernel/include/linux/ruclist.h

下面介绍rculist中的函数或宏

1、list_next

/*
 * return the ->next pointer of a list_head in an rcu safe
 * way, we must not access it directly
 */
#define list_next_rcu(list) (*((struct list_head __rcu **)(&(list)->next)))

此宏目的是获取list->next成员的地址


# define __rcu __attribute__((noderef, address_space(4)))        标示在地址空间4,并且地址有效

此宏是判断该地址是否有效



2、list_add

/**
 * list_add_rcu - add a new entry to rcu-protected list
 * @new: new entry to be added
 * @head: list head to add it after
 *
 * Insert a new entry after the specified head.
 * This is good for implementing stacks.
 *
 * The caller must take whatever precautions are necessary
 * (such as holding appropriate locks) to avoid racing
 * with another list-mutation primitive, such as list_add_rcu()
 * or list_del_rcu(), running on this same list.
 * However, it is perfectly legal to run concurrently with
 * the _rcu list-traversal primitives, such as
 * list_for_each_entry_rcu().
 */
static inline void list_add_rcu(struct list_head *new, struct list_head *head)
{
__list_add_rcu(new, head, head->next);
}

此函数是添加新条目到一个条目之后,是基于__list_add_rcu的上层函数。

/*
 * Insert a new entry between two known consecutive entries.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_add_rcu(struct list_head *new,
struct list_head *prev, struct list_head *next)
{
new->next = next;
new->prev = prev;
rcu_assign_pointer(list_next_rcu(prev), new);
next->prev = new;
}

此函数添加一个新条目到两个条目之间

new->next = next;
new->prev = prev;

必须是先给新条目next、prev值,然后再修改旧next、prev条目值,这样让已经获取prev条目值的并发读遍历线程不会中断

rcu_assign_pointer(list_next_rcu(prev), new);  这是给rcu机制保护的指针赋值,list_next_rcu(prev)这是获取前条目的next地址,rcu_assign_pointer这是rcu的发布订阅机制,保证读线程要不就是获取前条目next的旧值,要不就是赋值完成后的新值,这个rcu保护机制是防止编译器优化时将语句顺序优化,从而导致读线程获取的地址是未赋值的或不完全的,出现错误,这个机制是通过smp内存屏障实现的,内存屏障保证指针的内存数据已经赋值完成。


3、/**
 * list_add_tail_rcu - add a new entry to rcu-protected list
 * @new: new entry to be added
 * @head: list head to add it before
 *

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值