內核 current宏解析


Technorati 標簽: current thread_info

     在內核中,可以通過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的內核棧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM