我试图了解current
宏的工作原理,因此开始浏览Linux内核源代码版本4.19。试图了解x86架构
include / asm-generic / current.h:8
#define get_current() (current_thread_info()->task)
#define current get_current()
然后我试图找到current_thread_info()的定义。
include / linux / thread_info.h
#ifdef CONFIG_THREAD_INFO_IN_TASK
/*
* For CONFIG_THREAD_INFO_IN_TASK kernels we need <asm/current.h> for the
* definition of current, but for !CONFIG_THREAD_INFO_IN_TASK kernels,
* including <asm/current.h> can cause a circular dependency on some platforms.
*/
#include <asm/current.h>
#define current_thread_info() ((struct thread_info *)current)
#endif
然后我尝试查找当前定义
arch / x86 / include / asm / current.h
DECLARE_PER_CPU(struct task_struct *, current_task);
static __always_inline struct task_struct *get_current(void)
{
return this_cpu_read_stable(current_task);
}
#define current get_current()
get_current()再次返回struct task_struct,为什么我们在current_thread_info()中将其类型转换为struct thread_info。
能请您解释一下如何执行电流。我读到它放在内核堆栈顶部或底部的某个地方
答案 0 :(得分:0)
要投射指针-struct thread_info thread_info
是first member of the struct task_struct
:
struct task_struct {
#ifdef CONFIG_THREAD_INFO_IN_TASK
/*
* For reasons of header soup (see current_thread_info()), this
* must be the first element of task_struct.
*/
struct thread_info thread_info;
#endif
强制转换是合法的-我们正在返回指向struct
的第一个成员的指针。它可能使用类似的¤t->thread_info
,但是如果在某些情况下struct task_struct
的定义是 opaque (即它是不完整的类型),则不能使用它!
关于DECLARE_PER_CPU
的工作方式,这取决于。您过去所学的内容可能不再适用于此。使用特殊的宏读取和更新用DECLARE_PER_CPU
声明的变量。其他
这是因为在x86上,读取是通过特殊的段寄存器进行的。然后,其他CPU架构必须使用完全不同的方法来访问每CPU值。
通常,应使用this_cpu_read
读取per-cpu变量,这不允许GCC以任何方式对其进行缓存,但是当前线程信息是一个例外,因为当前线程始终在当前线程中运行它在什么CPU上。来自arch/x86/include/asm/percpu.h
:
/*
* this_cpu_read() makes gcc load the percpu variable every time it is
* accessed while this_cpu_read_stable() allows the value to be cached.
* this_cpu_read_stable() is more efficient and can be used if its value
* is guaranteed to be valid across cpus. The current users include
* get_current() and get_thread_info() both of which are actually
* per-thread variables implemented as per-cpu variables and thus
* stable for the duration of the respective task.
*/