您的位置:首页 > 其它

获取当前进程指针

2011-07-18 20:03 302 查看
/**2011年4月8日22:49:50*作者:张超*email:uestczhangchao@gmail.com*Linux2.6.32.25中如何获得当前进程的指针?*///Thread_info.h//申明per_cpu_kernel_stack变量,它在其它位置定义,见下文内容.
DECLARE_PER_CPU(unsignedlong,kernel_stack);
staticinlinestructthread_info*current_thread_info(void)
{
structthread_info*ti;//存放thread_info的指针
ti=(void*)(percpu_read_stable(kernel_stack)+
KERNEL_STACK_OFFSET-THREAD_SIZE);
returnti;
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

//取得相应当前cpu上thread_info所在的地址,返回值是整数

//Percpu.h
#definepercpu_read_stable(var)percpu_from_op("mov",per_cpu__##var,\
"p"(&per_cpu__##var))

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

//下层实际的操作

#definepercpu_from_op(op,var,constraint)\

({\

typeof(var)ret__;\

switch(sizeof(var)){\

case1:\

asm(op"b"__percpu_arg(1)",%0"\

:"=q"(ret__)\

:constraint);\

break;\

case2:\

asm(op"w"__percpu_arg(1)",%0"\

:"=r"(ret__)\

:constraint);\

break;\

case4:\

asm(op"l"__percpu_arg(1)",%0"\

:"=r"(ret__)\

:constraint);\

break;\

case8:\

asm(op"q"__percpu_arg(1)",%0"\

:"=r"(ret__)\

:constraint);\

break;\

default:__bad_percpu_size();\

}\

ret__;\

})

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

per_cpu__kernel_stack是在下面的代码中定义的:

DEFINE_PER_CPU(unsignedlong,kernel_stack)=

(unsignedlong)&init_thread_union-KERNEL_STACK_OFFSET+THREAD_SIZE;

externunionthread_unioninit_thread_union;

unionthread_union{

structthread_infothread_info;

unsignedlongstack[THREAD_SIZE/sizeof(long)];

};

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

thread_union是一个联合体,里面定义了thread_info结构和堆栈结构,THREAD_SIZE在32位平台上一般定义为4K,所以stack的大小其实就是4KB,这就是初始任务在核心里所拥有的所有空间,除去thread_info和KERNEL_STACK_OFFSET占用的空间后,就是任务在核心里实际拥有堆栈的大小。KERNEL_STACK_OFFSET定义为5*8,由于是unsignedlong,所以堆栈底部以上还有5*8*4B=200B的空间用来存放程序运行时相关的环境参数。
//Init_task.c23
/*
*Initialthreadstructure.
*
*WeneedtomakesurethatthisisTHREAD_SIZEalignedduetothe
*wayprocessstacksarehandled.Thisisdonebyhavingaspecial
*"init_task"linkermapentry..
*///Init_task.c
structtask_structinit_task=INIT_TASK(init_task);

unionthread_unioninit_thread_union__init_task_data=

{INIT_THREAD_INFO(init_task)};

//Sched.hthread_union

unionthread_union{

structthread_infothread_info;

unsignedlongstack[THREAD_SIZE/sizeof(long)];

};

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

/*
*INIT_TASKisusedtosetupthefirsttasktable,touchat
*yourownrisk!.Base=0,limit=0x1fffff(=2MB)
*/
#defineINIT_TASK(tsk)\

{\

.state=0,\

.stack=&init_thread_info,\

.usage=ATOMIC_INIT(2),\

.flags=PF_KTHREAD,\

.lock_depth=-1,\

.prio=MAX_PRIO-20,\

.static_prio=MAX_PRIO-20,\

.normal_prio=MAX_PRIO-20,\

.policy=SCHED_NORMAL,\

.cpus_allowed=CPU_MASK_ALL,\

.mm=NULL,\

.active_mm=&init_mm,\

.se={\

.group_node=LIST_HEAD_INIT(tsk.se.group_node),\

},\

.rt={\

.run_list=LIST_HEAD_INIT(tsk.rt.run_list),\

.time_slice=HZ,\

.nr_cpus_allowed=NR_CPUS,\

},\

.tasks=LIST_HEAD_INIT(tsk.tasks),\

.pushable_tasks=PLIST_NODE_INIT(tsk.pushable_tasks,MAX_PRIO),\

.ptraced=LIST_HEAD_INIT(tsk.ptraced),\

.ptrace_entry=LIST_HEAD_INIT(tsk.ptrace_entry),\

.real_parent=&tsk,\

.parent=&tsk,\

.children=LIST_HEAD_INIT(tsk.children),\

.sibling=LIST_HEAD_INIT(tsk.sibling),\

.group_leader=&tsk,\

.real_cred=&init_cred,\

.cred=&init_cred,\

.cred_guard_mutex=\

__MUTEX_INITIALIZER(tsk.cred_guard_mutex),\

.comm="swapper",\

.thread=INIT_THREAD,\

.fs=&init_fs,\

.files=&init_files,\

.signal=&init_signals,\

.sighand=&init_sighand,\

.nsproxy=&init_nsproxy,\

.pending={\

.list=LIST_HEAD_INIT(tsk.pending.list),\

.signal={{0}}},\

.blocked={{0}},\

.alloc_lock=__SPIN_LOCK_UNLOCKED(tsk.alloc_lock),\

.journal_info=NULL,\

.cpu_timers=INIT_CPU_TIMERS(tsk.cpu_timers),\

.fs_excl=ATOMIC_INIT(0),\

.pi_lock=__SPIN_LOCK_UNLOCKED(tsk.pi_lock),\

.timer_slack_ns=50000,/*50usecdefaultslack*/\

.pids={\

[PIDTYPE_PID]=INIT_PID_LINK(PIDTYPE_PID),\

[PIDTYPE_PGID]=INIT_PID_LINK(PIDTYPE_PGID),\

[PIDTYPE_SID]=INIT_PID_LINK(PIDTYPE_SID),\

},\

.dirties=INIT_PROP_LOCAL_SINGLE(dirties),\

INIT_IDS\

INIT_PERF_EVENTS(tsk)\

INIT_TRACE_IRQFLAGS\

INIT_LOCKDEP\

INIT_FTRACE_GRAPH\

INIT_TRACE_RECURSION\

INIT_TASK_RCU_PREEMPT(tsk)\

}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

初始化thread_info,传入参数是任务结构体

#defineINIT_THREAD_INFO(tsk)\

{\

.task=&tsk,\

.exec_domain=&default_exec_domain,\

.flags=0,\

.cpu=0,\

.preempt_count=INIT_PREEMPT_COUNT,\

.addr_limit=KERNEL_DS,\

.restart_block={\

.fn=do_no_restart_syscall,\

},\

}


.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

//宏定义展开过后的结果
structthread_info*ti;
ti=(void*)(({typeof(per_cpu__kernel_stack)ret__;
switch(sizeof(per_cpu__kernel_stack)){
case1:__asm("movb%%fs:%P1,%0":"=q"(ret__):"p"(&per_cpu__kernel_stack));break;
case2:__asm("movw%%fs:%P1,%0":"=r"(ret__):"p"(&per_cpu__kernel_stack));break;
case4:__asm("movl%%fs:%P1,%0":"=r"(ret__):"p"(&per_cpu__kernel_stack));break;
case8:__asm("movq%%fs:%P1,%0":"=r"(ret__):"p"(&per_cpu__kernel_stack));break;
default:__bad_percpu_size();}ret__;})+KERNEL_STACK_OFFSET-THREAD_SIZE);

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

总结:该版本内核和以前版本的内核在获得当前任务指针的方法上有很大的不同,以前是通过如下汇编指令实现的:movl$-8192,%eax;andl%esp,%eax来实现的,执行完这两条指令后,eax中存放的就是thread_info的地址。而现在的代码中再也找不到这样的指令了,以前SMP共享数据很多依靠自旋锁来达到目的,自旋锁是一种忙等锁,在一定程度上造成了进行自旋的CPU上CPU利用率的下降,随着内核的不断发展,更多的使用每个CPU数据(per_cpu_data)的概念,在每一个处理器中各自维护一个以前在多个CPU之间进行共享的数据,如当前运行的任务结构体,以前就是在多个CPU之间共享的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: