Chinaunix首页 | 论坛 | 博客
  • 博客访问: 288053
  • 博文数量: 68
  • 博客积分: 3061
  • 博客等级: 中校
  • 技术积分: 652
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-27 11:39
文章分类

全部博文(68)

文章存档

2018年(1)

2017年(2)

2016年(1)

2014年(2)

2012年(6)

2011年(14)

2010年(38)

2008年(4)

我的朋友

分类: LINUX

2010-09-25 17:34:01

这两个都是内核用来新建核态线程的。先看原型:
struct task_struct *kthread_create(int (*threadfn)(void *data),
  void *data,
  const char namefmt[],
  ...)

pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)

一个返回task描述符,一个返回pid_t.


在看源码:
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
struct pt_regs regs;

memset(®s, 0, sizeof(regs));

regs.ARM_r1 = (unsigned long)arg;
regs.ARM_r2 = (unsigned long)fn;
regs.ARM_r3 = (unsigned long)kernel_thread_exit;
regs.ARM_pc = (unsigned long)kernel_thread_helper;
regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;

return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
}

kernel_thread最终是调用了do_fork实现。


struct task_struct *kthread_create(int (*threadfn)(void *data),
  void *data,
  const char namefmt[],
  ...)
{
struct kthread_create_info create;

create.threadfn = threadfn;
create.data = data;
init_completion(&create.done);

spin_lock(&kthread_create_lock);
list_add_tail(&create.list, &kthread_create_list);
spin_unlock(&kthread_create_lock);

wake_up_process(kthreadd_task);
wait_for_completion(&create.done);

if (!IS_ERR(create.result)) {
struct sched_param param = { .sched_priority = 0 };
va_list args;

va_start(args, namefmt);
vsnprintf(create.result->comm, sizeof(create.result->comm),
 namefmt, args);
va_end(args);
/*
* root may have changed our (kthreadd's) priority or CPU mask.
* The kernel thread should not inherit these properties.
*/
sched_setscheduler_nocheck(create.result, SCHED_NORMAL, ¶m);
set_cpus_allowed_ptr(create.result, cpu_all_mask);
}
return create.result;
}

而kthread_create,现在还看不出怎么实现的。只能一行行读了。
1.创建并初始化一个struct kthread_create_info create;把要实现的函数赋给
  create->threadfn = threadfn;
2.初始化完成量:create->done.
3.将create挂到一个叫kthread_create_list的全局链表上
4.唤醒一个叫kthreadd_task的task。
5.等待wait_for_completion(&create.done)。
------------------------------------------------------------------------
 kthreadd_task是在(start_kernel->)rest_init中被赋值,其实就是被kernel_thread创建出来的kthreadd的task描述符。也就说要看kthreadd。
 1.tsk = current;
 2.进入for死循环,将当前task设置为TASK_INTERRUPTIBLE,判断
   kthread_create_list是否为空,为空一直睡眠,否则,进入while循环,while的退出条件为kthread_create_list为空
 3.在while循环中做的事情:取出一个create,调用creaet_kthread
 4.create_kthread调用kernel_thread其一个kthread线程,也就是说,一个create就有一个kthread线程。

 5.kthread做的事情:
   a.取出create
   b.定义并初始化一个struct kthread self。
struct kthread {
int should_stop;
struct completion exited;
};
   c.current->vfork_done = &self.exited;
   d.__set_current_state(TASK_UNINTERRUPTIBLE);
    create->result = current;将当前task状态设置为TASK_UNINTERRUPTIBLE,并将task描述符赋给create->result。后面看到这就是kthread_create返回的task描述符。
   e.唤醒等待creaet->done完成量的task,并通过schedule()让出cpu。
------------------------------------------------------------------------
6.返回create->result.
阅读(1416) | 评论(0) | 转发(0) |
0

上一篇:一些宏定义的位置

下一篇:启动顺序

给主人留下些什么吧!~~