• 内核 current宏解析


    Technorati 标签:

         在内核中,可以通过current宏来获得当前执行进程的task_struct指针。现在来简要分析以下:

         最原始的定义如下:

       #define current get_current()
       #define get_current() (current_thread_info()->task)
       可以看出,current调用了 current_thread_info函数,此函数的内核路径为: arch/arm/include/asm/thread_info.h,内核版本为2.6.32.65

        static inline struct thread_info *current_thread_info(void)
       {
            register unsigned long sp asm ("sp");
            return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
       }

       其中 thread_info结构体如下:

    struct thread_info {
    	unsigned long		flags;		/* low level flags */
    	int			preempt_count;	/* 0 => preemptable, <0 => bug */
    	mm_segment_t		addr_limit;	/* address limit */
    	struct task_struct	*task;		/* main task structure */
    	struct exec_domain	*exec_domain;	/* execution domain */
    	__u32			cpu;		/* cpu */
    	__u32			cpu_domain;	/* cpu domain */
    	struct cpu_context_save	cpu_context;	/* cpu context */
    	__u32			syscall;	/* syscall number */
    	__u8			used_cp[16];	/* thread used copro */
    	unsigned long		tp_value;
    	struct crunch_state	crunchstate;
    	union fp_state		fpstate __attribute__((aligned(8)));
    	union vfp_state		vfpstate;
    #ifdef CONFIG_ARM_THUMBEE
    	unsigned long		thumbee_state;	/* ThumbEE Handler Base register */
    #endif
    	struct restart_block	restart_block;
    };

        当内核线程执行到此处时,其SP堆栈指针指向调用进程所对应的内核线程的栈顶。通过 sp & ~(THREAD_SIZE-1)向上对齐,达到栈底部。如下图所示

         image

         将结果强制类型转换为thread_info类型,此类型中有一个成员为task_struct,它就是 当前正在运行进程的 task_struct指针。

      

    备注:

        在内核中,进程的task_struct是由slab分配器来分配的,slab分配器的优点是对象复用和缓存着色。

        联合体:

        #define THREAD_SIZE        8192       //内核线程栈 可以通过内核配置成4K 或者 8K ,此处是8K   。在X86体系结构上,32位的内核栈为8K,64位的为16K。

        union thread_union {
        struct thread_info thread_info;                            // sizeof(thread_info) =
        unsigned long stack[THREAD_SIZE/sizeof(long)];     //stack 大小为 8K,union联合体的地址是严格按照小端排布的,因此,内核栈的低位地址是thread_info结构体。 
        };

        整个8K的空间,顶部供进程堆栈使用,最下部为thread_info。从用户态切换到内核态时,进程的内核栈还是空的,所以sp寄存器指向栈顶,一旦有数据写入,sp的值就会递减,内核栈按需扩展,理论上最大可扩展到 【8192- sizeof(thread_info) 】大小,考虑到函数的现场保护,往往不会有这么大的栈空间。内核在代表进程执行时和所有的中断服务程序执行时,共享8K的内核栈。

  • 相关阅读:
    <转>c#调用C++DLL类型转换
    <转>CB2010使用一段时间总结。(Ansi>Unicode)
    Sql的自定义聚合函数,挺费劲。
    关于 MSDN 说 Lock 应该用private 对象锁定的测试。
    热门JQuery插件
    偶然发现 RouteDebuge 的作者是一个超牛的家伙。
    jquery.query 插件的设计问题。
    JQuery UI 调整笔记
    JQuery tr:visible IE8 失效.
    CS0016 一个解决方案:
  • 原文地址:https://www.cnblogs.com/cherishui/p/4255690.html
Copyright © 2020-2023  润新知