一些内核进程调度API (6)

//此函数用以终止输入参数k对应的进程
//返回值就是 int (*threadfn)(void *data) 的int值
int kthread_stop(struct task_struct *k)
{
struct kthread *kthread;
int ret;


trace_sched_kthread_stop(k);


get_task_struct(k);
kthread = to_live_kthread(k);
if (kthread) {
set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);
__kthread_unpark(k, kthread);
wake_up_process(k);
wait_for_completion(&kthread->exited);
}
ret = k->exit_code;
put_task_struct(k);


trace_sched_kthread_stop_ret(ret);
return ret;
}


//将 wait 加入到 q所在等待队列的头部,wait需要满足是一个单独节点,不与别的元素相干
void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
{
unsigned long flags;


wait->flags &= ~WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
if (list_empty(&wait->task_list))
__add_wait_queue(q, wait);
set_current_state(state);
spin_unlock_irqrestore(&q->lock, flags);
}


//将 wait 加入到 q所在等待队列的尾部,wait需要满足是一个单独节点,不与别的元素相干
void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state)
{
unsigned long flags;


wait->flags |= WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
if (list_empty(&wait->task_list))
__add_wait_queue_tail(q, wait);
set_current_state(state);
spin_unlock_irqrestore(&q->lock, flags);
}


//将 wait 从 q所在的等待队列中删除
void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
{
unsigned long flags;


spin_lock_irqsave(&q->lock, flags);
__remove_wait_queue(q, wait);
spin_unlock_irqrestore(&q->lock, flags);
}


//改变p的调度策略及实时优先级
int sched_setscheduler(struct task_struct *p, int policy,
               const struct sched_param *param)
{
return _sched_setscheduler(p, policy, param, true);
}


/*进程的优先级分为 静态优先级, 动态优先级
  静态优先级:进程在创建之初就分配的值,100-139,越小越紧急,static_prio=120+nice
  动态优先级:随着进程在内核的时间而改变,是内核调度的参考依据,与进程调度策略 policy 有关
*/
//更改p的nice值,也即修改它的静态优先级
void set_user_nice(struct task_struct *p, long nice)
{
int old_prio, delta, queued;
unsigned long flags;
struct rq *rq;


if (task_nice(p) == nice || nice < MIN_NICE || nice > MAX_NICE)
return;
/*
* We have to be careful, if called from sys_setpriority(),
* the task might be in the middle of scheduling on another CPU.
*/
rq = task_rq_lock(p, &flags);
/*
* The RT priorities are set via sched_setscheduler(), but we still
* allow the 'normal' nice value to be set - but as expected
* it wont have any effect on scheduling until the task is
* SCHED_DEADLINE, SCHED_FIFO or SCHED_RR:
*/
if (task_has_dl_policy(p) || task_has_rt_policy(p)) {
p->static_prio = NICE_TO_PRIO(nice);
goto out_unlock;
}
queued = task_on_rq_queued(p);
if (queued)
dequeue_task(rq, p, 0);


p->static_prio = NICE_TO_PRIO(nice);
set_load_weight(p);
old_prio = p->prio;
p->prio = effective_prio(p);
delta = p->prio - old_prio;


if (queued) {
enqueue_task(rq, p, 0);
/*
* If the task increased its priority or is running and
* lowered its priority, then reschedule its CPU:
*/
if (delta < 0 || (delta > 0 && task_running(rq, p)))
resched_curr(rq);
}
out_unlock:
task_rq_unlock(rq, p, &flags);
}


//获取进程的nice值
static inline int task_nice(const struct task_struct *p)
{
return PRIO_TO_NICE((p)->static_prio);
}


//唤醒睡眠状态的进程,使进程变为 TASK_RUNNING态,从而能被CPU重新调度执行
int wake_up_process(struct task_struct *p)
{
WARN_ON(task_is_stopped_or_traced(p));
return try_to_wake_up(p, TASK_NORMAL, 0);
}


//让当前进程所占用的内核空间短暂让步,短暂释放占用的CPU资源,给其他进程执行的机会
void yield(void)
[例]
result=kthread_create_on_node(my_function,NULL,-1,namefrm);
wake_up_process(result);
yield(); //此时 my_function得以运行,没有yield,父进程不会让步

猜你喜欢

转载自blog.csdn.net/dummkopfer/article/details/80466948