3.5:进程调度-调度

一:调度函数schedule

1:检测任务状态,设置可中断任务的状态位RUNNING

void schedule(void)
{
        int i,next,c;
        struct task_struct ** p;

/* check alarm, wake up any interruptible tasks that have got a signal */

        for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
                if (*p) {
                        if ((*p)->alarm && (*p)->alarm < jiffies) {
                                        (*p)->signal |= (1<<(SIGALRM-1));
                                        (*p)->alarm = 0;
                                }
                        if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&
                        (*p)->state==TASK_INTERRUPTIBLE)
                                (*p)->state=TASK_RUNNING;
                }

2:通过while循环,找到counter(时间片/优先级)最长的任务

/* this is the scheduler proper: */
        while (1) {
                c = -1;
                next = 0;
                i = NR_TASKS;
                p = &task[NR_TASKS];
                while (--i) {
                        if (!*--p)
                                continue;
                        if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
                                c = (*p)->counter, next = i;
                }

3:重新设置所有进程的counter

        if (c) break;
        for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
                if (*p)
                        (*p)->counter = ((*p)->counter >> 1) +
                                        (*p)->priority;
}

4:切换到该任务并执行
switch_to(next);

二:睡眠函数

1:sleep_on(不可中断的等待状态)

void sleep_on(struct task_struct **p)
{
        struct task_struct *tmp;

        if (!p)
                return;
        if (current == &(init_task.task))
                panic("task[0] trying to sleep");
        tmp = *p;
        *p = current;
        current->state = TASK_UNINTERRUPTIBLE;
        schedule();
        //当sche调度结束后重新回到这,那么大家都在等同样的资源,所以就将该程序重新变为就绪态
        if (tmp)
                tmp->state=0;
}

2:interruptible_sleep_on(可中断状态)

void interruptible_sleep_on(struct task_struct **p)
{
        struct task_struct *tmp;

        if (!p)
                return;
        if (current == &(init_task.task))
                panic("task[0] trying to sleep");
        tmp=*p;
        *p=current;
repeat: current->state = TASK_INTERRUPTIBLE;
        schedule();
        if (*p && *p != current) {
                (**p).state=0;
                goto repeat;
        }
        *p=NULL;
        if (tmp)
                tmp->state=0;
}

三:唤醒函数

void wake_up(struct task_struct **p)
{
        if (p && *p) {
                (**p).state=0;
                *p=NULL;
        }
}

四:等待函数

pid>0,等待进程号等于pid的子进程
pid=0,等待进程组中的任意一子进程
pid<-1,等待进程组号等于pid绝对值的任何子进程
pid=-1,等待任何子进程

int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)

1)根据pid,找到需要处理的子进程

for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
                if (!*p || *p == current)
                        continue;
                if ((*p)->father != current->pid)
                        continue;
                if (pid>0) {
                        if ((*p)->pid != pid)
                                continue;
                } else if (!pid) {
                        if ((*p)->pgrp != current->pgrp)
                                continue;
                } else if (pid != -1) {
                        if ((*p)->pgrp != -pid)
                                continue;
                }

2)根据子进程的状态,进行相应的处理

   switch ((*p)->state) {
            case TASK_STOPPED:
                    if (!(options & WUNTRACED))
                            continue;
                    put_fs_long(0x7f,stat_addr);
                    return (*p)->pid;
            case TASK_ZOMBIE:
                    current->cutime += (*p)->utime;
                    current->cstime += (*p)->stime;
                    flag = (*p)->pid;
                    code = (*p)->exit_code;
                    release(*p);
                    put_fs_long(code,stat_addr);
                    return flag;
            default:
                    flag=1;
                    continue;
    }

3)如果该子进程没有退出或处于僵死状态,则置当前进程位可中断等待状态

if (flag) {
        if (options & WNOHANG)
                return 0;
        current->state=TASK_INTERRUPTIBLE;
        schedule();
        if (!(current->signal &= ~(1<<(SIGCHLD-1))))
                goto repeat;
        else
                return -EINTR;
}
return -ECHILD;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值