2008年2月16日 星期六

Linux Process - 3

Process Kernel Stack 預設為 8KB,以 THREAD_SIZE 表示,也可以設定成 4KB
這代表每個行程在 Kernel Mode 所能使用的最大堆疊空間:

定義於 include/asm-i386/thread_info.h

#ifdef CONFIG_4KSTACKS
#define THREAD_SIZE  (4096)
#else
#define THREAD_SIZE  (8192)
#endif

在 Process Descriptor (即 struct task_struct) 中,有個 thread_info 的指標
會指向該行程的 struct thread_info 的位址,用來描述較為低階的行程資訊
這個 thread_info 會與 kernel stack 共用記憶體空間,因為是以 union 的方式宣告
定義於 include/linux/sched.h

union thread_union {
  struct thread_info thread_info;
  unsigned long stack[THREAD_SIZE/sizeof(long)];
};

其中,thread_info 位於記憶體的低位址處,而 stack 則起始於高位址處
堆疊的位置以暫存器 esp 指示,如下圖:


struct task_struct 及 struct thread_info 分別會以 thread_infotask 的指標互連
如此便可經由 esp 換算取得指向目前行程的指標,也就是 current 這個巨集的實作方法:

定義於 include/asm-i386/current.h

static inline struct task_struct * get_current(void)
{
  return current_thread_info()->task;
}
#define current get_current()

定義於 include/asm-i386/thread_info.h

/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
  struct thread_info *ti;
  __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1)));
  return ti;
}
/* how to get the current stack pointer from C */
register unsigned long current_stack_pointer asm("esp") __attribute_used__;

沒有留言: