进程调度API之wake_up_process
2017-12-22 14:17
435 查看
int wake_up_process(struct task_struct *p) 这个函数用于唤醒一个task。 其使用的例程如下: static void cmtp_reset_ctr(struct capi_ctr *ctrl) { struct cmtp_session *session = ctrl->driverdata; BT_DBG("ctrl %p", ctrl); capi_ctr_down(ctrl); atomic_inc(&session->terminate); wake_up_process(session->task); } 例如这个例子中就通过wake_up_process 来唤醒session->task 其源码分析如下: int wake_up_process(struct task_struct *p) { return try_to_wake_up(p, TASK_NORMAL, 0); } 唤醒p到TASK_NORMAL 状态 static int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) { unsigned long flags; int cpu, success = 0; /* * If we are going to wake up a thread waiting for CONDITION we * need to ensure that CONDITION=1 done by the caller can not be * reordered with p->state check below. This pairs with mb() in * set_current_state() the waiting thread does. */ smp_mb__before_spinlock(); raw_spin_lock_irqsave(&p->pi_lock, flags); #如果task的状态已经等于要设的状态了,就退出吧,从这里知道,调用wake_up_process 不一定非得是sleep的task.正常task #也是可以的,只是不起作用而已,在这里就退出了. if (!(p->state & state)) goto out; trace_sched_waking(p); /* We're going to change ->state: */ success = 1; #获得要wakeup 的task 原本是运行到哪个cpu上的 cpu = task_cpu(p); /* * Ensure we load p->on_rq _after_ p->state, otherwise it would * be possible to, falsely, observe p->on_rq == 0 and get stuck * in smp_cond_load_acquire() below. * * sched_ttwu_pending() try_to_wake_up() * [S] p->on_rq = 1; [L] P->state * UNLOCK rq->lock -----. * \ * +--- RMB * schedule() / * LOCK rq->lock -----' * UNLOCK rq->lock * * [task p] * [S] p->state = UNINTERRUPTIBLE [L] p->on_rq * * Pairs with the UNLOCK+LOCK on rq->lock from the * last wakeup of our task and the schedule that got our task * current. */ smp_rmb(); #要唤醒的task 不在自己的rq上,也就是要唤醒其他rq上的task,所以这里会做remote wake up. if (p->on_rq && ttwu_remote(p, wake_flags)) goto stat; #ifdef CONFIG_SMP /* * Ensure we load p->on_cpu _after_ p->on_rq, otherwise it would be * possible to, falsely, observe p->on_cpu == 0. * * One must be running (->on_cpu == 1) in order to remove oneself * from the runqueue. * * [S] ->on_cpu = 1; [L] ->on_rq * UNLOCK rq->lock * RMB * LOCK rq->lock * [S] ->on_rq = 0; [L] ->on_cpu * * Pairs with the full barrier implied in the UNLOCK+LOCK on rq->lock * from the consecutive calls to schedule(); the first switching to our * task, the second putting it to sleep. */ smp_rmb(); /* * If the owning (remote) CPU is still in the middle of schedule() with * this task as prev, wait until its done referencing the task. * * Pairs with the smp_store_release() in finish_lock_switch(). * * This ensures that tasks getting woken will be fully ordered against * their previous state and preserve Program Order. */ smp_cond_load_acquire(&p->on_cpu, !VAL); p->sched_contributes_to_load = !!task_contributes_to_load(p); #先将task的状态设置为TASK_WAKING p->state = TASK_WAKING; #task 如果是在等待io的时候sleep。则先结束这次io 操作? if (p->in_iowait) { delayacct_blkio_end(); atomic_dec(&task_rq(p)->nr_iowait); } #根据wakup cpu选择要rq要运行到哪个cpu上 cpu = select_task_rq(p, p->wake_cpu, SD_BALANCE_WAKE, wake_flags); #如果wakeup后的cpu 和之前task 运行的cpu 不相等,则设置需要迁移的flag,方便以后进行迁移工作。并通过set_task_cpu将task #wakeup 后的cpu保存在task中 if (task_cpu(p) != cpu) { wake_flags |= WF_MIGRATED; set_task_cpu(p, cpu); } #else /* CONFIG_SMP */ if (p->in_iowait) { delayacct_blkio_end(); atomic_dec(&task_rq(p)->nr_iowait); } #endif /* CONFIG_SMP */ #执行wakeup task 的操作 ttwu_queue(p, cpu, wake_flags); stat: #更新rq中相关统计数据 ttwu_stat(p, cpu, wake_flags); out: raw_spin_unlock_irqrestore(&p->pi_lock, flags); return success; }
相关文章推荐
- 进程调度API之__wake_up
- 进程调度API之__wake_up_sync
- 进程调度API之autoremove_wake_function
- 进程调度API之preempt_count_add/preempt_count_sub
- 进程调度API之complete
- 进程调度API之finish_wait
- Linux使用wake_up_interruptible()唤醒注册到等待队列上的进程
- 创建进程API CreateProcess Demo
- Linux使用wake_up_interruptible()唤醒注册到等待队列上的进程
- 创建进程API CreateProcess Demo
- 进程调度API之preempt_count_add(val)/preempt_count_sub(val)
- 进程调度API之preempt_schedule
- 进程调度API之init_waitqueue_head
- 进程调度API之yield
- java9新特性-Process 进程 API
- 进程调度API之set_cpus_allowed_ptr
- 进程调度API之task_nice
- 进程调度API之cond_resched
- linux0.11进程睡眠sleep_on函数和唤醒wake_up函数分析
- GetProcessMemoryInfo API取得进程所用的内存