《Linux内核分析》MOOC课程之从迷你Linux内核角度理解进程时间轮片调度(未完)

北城余情 提交于 2020-02-28 19:53:38



代码分析

  1. mypcb.h


  2. mymain.c

    上面这段代码主要完成了对0号进程的初始化,即pid置为0,状态state置为0(即runnable状态),进程入口及当前进程的线程的ip指向my_process,线程的sp指向当前进程的进程堆栈,由于目前只有0号进程,所以next指针指向自己形成一个单PCB链表。

    上面这段代码主要是扩充循环链表,使用memcpy()复制0号进程的状态给创建的从1号到MAX_TASK_NUM-1号进程,并与0号进程一起构成一个循环PCB链表。

    上面这段代码功能是从循环PCB链表的task[0]启动0号进程,是通过使用了gcc的内联汇编来实现的。接下来我们具体分析该过程:

    初始堆栈状态:

    movl %1, %%esp

    push1 %1

    pushl %0

    ret

    popl %%ebp

    其实这段汇编代码是不会被执行的,因为ret \n\t后eip指向了0号进程的起始地址。

    上面这段代码实现每循环1千万次打印一下当前进程的pid,然后判断时钟中断是否将调度标志(my_need_sched)置为1,如果是1则将调度标志置为0,调用my_schedule(),避免消息机制,然后再打印一次当前进程的pid。

  3. myinterrupt.c

    my_time_handler()实现被调用每千次且调度标志(my_need_sched)不为1时,打印“>>>my_timer_handler here<<<”且将调度标志置为1,以便于my_schedule()在my_process()中可被调用。

    上面这段代码为进程调度函数容错处理及next和prev指针的定义与初始化。

    假设现在0号进程正在运行,而1号进程为unrunnable状态即next->state为-1,则进入创建进程分支:

    先将next->state置为0,指向下一进程,打印进程切换关系,然后执行汇编内容,从堆栈角度分析该内联汇编执行过程:

    堆栈初始状态

    pushl %%ebp

    movl %%esp, %0

    movl %%2, %%esp

    movl %%2, %%ebp

    movl $1f, %1

    pushl %3

    ret

上面这段代码功能为,如果当前进程所在PCB循环链表的下一个结点的状态state的值为零即下一进程状态为runnable时,切换到下一进程,再打印下切换关系。具体的上下文切换过程用gcc内联汇编写的,下面来通过图片分析:

寄存器初始状态

……

未完,待续



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!