代码之家  ›  专栏  ›  技术社区  ›  md.jamal

无法理解“当前”宏在x86体系结构中是如何工作的

  •  -1
  • md.jamal  · 技术社区  · 6 年前

    current 宏工作,所以开始浏览Linux内核源代码版本4.19。试图理解x86体系结构

    include/asm generic/current。h:8

    #define get_current() (current_thread_info()->task)
    #define current get_current()
    

    然后我试图找到当前线程的定义。

    include/linux/thread\u 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\u current()再次返回struct task\u struct,为什么要在current\u thread\u info()中将其类型转换为struct thread\u info。

    你能解释一下电流是如何被执行的吗。我在某个地方读到它被放在内核堆栈的顶部或底部

    1 回复  |  直到 6 年前
        1
  •  0
  •   Antti Haapala -- Слава Україні    6 年前

    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 . 它本可以用类似的方法 &current->thread_info 但如果 结构任务\u结构


    至于 DECLARE_PER_CPU 每个CPU声明\u 这是因为在x86上,读取是通过一个特殊的段寄存器进行的。其他CPU架构必须使用一些完全不同的方法来访问每CPU值。

    this_cpu_read 它不允许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.
     */