标签:
代码分析
mypcb.h
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。
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内联汇编写的,下面来通过图片分析:
寄存器初始状态
……
未完,待续
《Linux内核分析》MOOC课程之从迷你Linux内核角度理解进程时间轮片调度(未完)
标签:
原文地址:http://my.oschina.net/u/1169027/blog/387338