java开发系统内核:实现进程优先级

更详细的讲解和代码调试演示过程,请参看视频
Linux kernel Hacker, 从零构建本身的内核vue

咱们有了进程调度,目前来看,全部进程一概平等。咱们的调度算法是遍历每个进程,而后给每个进程必定的运行时间,而后再切换下一个进程。但实际运用上,进程间不会是平等的,有些进程承担着比较重要的工做,所以,它有理由得到更多的运行时间,例如内核进程,一些进程不是很重要,同理,它就不该该占用过分的CPU资源。本节,咱们要引入进程优先级的功能,让优先级高的进程得到更多的运行机会。算法

首先咱们须要改动的是对TASK结构体的定义(multi_task.h):微信

struct TASK {
    int sel, flags;
    int priority;
    struct TSS32 tss;
};

咱们增长了一个变量叫priority, 这个变量表明着进程的优先级,同时也是进程运行的时间片,这个值越大,进程得到的CPU运行时间就越多。TASK对象的相关处理函数也须要作相应改动,在multi_task.c中:markdown

struct TASK  *task_init(struct MEMMAN *memman) {
....
    task = task_alloc();
    task->flags = 2;  //active
    task->priority = 100;
    taskctl->running = 1;
    taskctl->now = 0;
    taskctl->tasks[0] = task;
    load_tr(task->sel);
    task_timer = timer_alloc();
    timer_settime(task_timer, task->priority);
    return task;
....
}

void task_run(struct TASK *task, int priority) {
    if (priority > 0) {
        task->priority = priority;
    }

    task->flags = 2;
    taskctl->tasks[taskctl->running] = task;
    taskctl->running++;
    return;
} 

void task_switch(void) {
    struct TASK *task;

    if (taskctl->running >= 2) {
        taskctl->now++;
        if (taskctl->now == taskctl->running) {
            taskctl->now = 0;
        }

        task = taskctl->tasks[taskctl->now];
        timer_settime(task_timer, task->priority);        
        farjmp(0, taskctl->tasks[taskctl->now]->sel);
    }

    return;
}

每一个任务分配时,它的优先级会默认设置成100,也就是该任务能得到1秒的运行时间。task_run多增长了一个参数,也就是任务优先级,当一个任务准备加入调度队列时,须要指定它的优先级,在task_switch中,任务切换时,咱们经过timer_settime来设置任务的运行时间,你们能够看到,时钟的长度设置为task->priority, 也就是说,任务的优先级同时也是任务的CPU运行时间。app

任务激活的相关代码也须要作改动,任务能够对应一个数据队列,当队列有数据抵达时,队列会把存储在其中的任务加入调度队列,这个功能的实现是在golobal_define.c中,所以,咱们也须要作相应改动:函数

int fifo8_put(struct FIFO8 *fifo, unsigned char data) {
....
    if (fifo->task != 0) {
        if (fifo->task->flags != 2) {
            task_run(fifo->task, 0);
        }
    }
....
}

当任务从新被激活时,咱们传入的优先级数值是0,根据task_run的实现,当优先级数值为0时,任务保持原有优先级不变。最后须要改动的是主入口函数,在write_vga_desktop.c中:ui

void CMain(void) {
....
for (i = 0; i < 2; i++) {
....
task_run(task_b[i], (i+1)*5);
...
}
....
}

咱们为第一个任务分配的优先级是5,第二个任务的优先级是10,也就是第二个任务获得的CPU时间是第一个任务的2倍。将上面代码编译运行时能够获得下面结果:url


咱们能够看到,第二个窗口计数数值大概是第一个窗口的2倍,这是由于第二个窗口对应的进程得到的CPU运行时间是第一个窗口两倍的缘故。spa

本节代码比较简单,这是为了下一次实现更复杂的进程调度功能:优先级队列作准备的,经过视频能够得到更加详细的代码讲解和演示效果。.net

本文分享自微信公众号 - Coding迪斯尼(gh_c9f933e7765d)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索