Linux Kernel Design second week Learning summary complete a simple time slice rotation multi-channel program kernel code

Source: Internet
Author: User
Tags constant definition prev git clone

Chen Chaojan Original works reproduced please specify the source "Linux kernel Analysis" MOOC course http://mooc.study.163.com/course/USTC-1000029000

First, using the virtual machine of the experimental building, observe the relationship between the mykernel of a dead loop and the clock interrupt.

步骤:
cd LinuxKernel/linux-3.9.4qemu -kernel arch/x86/boot/bzImage

Execution effects such as


Paste_image.png

View MYMAIN.C Now:


Paste_image.png

See Myinterrupt.c again:


Paste_image.png

From the execution effect, the My_timer_handler and My_start_kernel cycle is really alternating, about 100,000 times per cycle will be executed once timer_handler.

Second, for only the dead loop Mykernel to add the time slice function and recompile, observe the new Mykernel behavior

First clone mengning/mykernel , replace MYMAIN.C and myinterrupt.c, add Mypcb.h:

cd ~/LinuxKernel/linux-3.9.4
git clone https://github.com/mengning/mykernel.git mykernel_new
cd mykernel_new
cp mymain.c myinterrupt.c mypcb.h ../mykernel
cd ..

Then run make the recompile Mykernel:


Paste_image.png

And then run qemu -kernel arch/x86/boot/bzImage :

It is not difficult to observe the new Mykernel behavior, total 0 1 2 3 A total of four process, the new Mykernel executes n process for a certain time, will change to (n+1)% 4th process continues to execute,
will be printed at the replacement >>> my_schedule <<< , and>>> switch n to (n+1)%4 <<<
Such as:

The 3rd process cuts to the moment of number No. 0:


Paste_image.png

The 1th process cuts to the moment of number 2nd:


Paste_image.png

Knowing the behavior of Mykernel, here's how mymain.c and myinterrupt.c do it:
You can first see a constant definition on line 10th of Mypcb.h

#define MAX_TASK_NUM        4

Then observe the Mykernel execution entry function My_start_kernel the MYMAIN.C loop starting from line 36th

    for (i=1;i<max_task_num;i++) {memcpy (&task[i],&task[0],sizeof (TPCB)); Task[i].pid = i; Task[i].state =-1; TASK[I].THREAD.SP = (UnsignedLong) &task[i].stack[kernel_stack_size-1]; Task[i].next = task[i-1].next; task[i-1].next = &task[i]; }/* Start process 0 by task[0] */pid = 0; my_current_task = &task [PID]; asm volatile  ( "movl%1,%%esp\n\t" /* set task[ PID].THREAD.SP to ESP */ "PUSHL%1\n\t" /* push EBP */" PUSHL%0\n\t "/* push Task[pid].thread.ip */" ret \n\t "/* pop task[pid].thread.ip to EIP */" Popl%%ebp\n\t ":: 
                               
                                 "C" (Task[pid].thread.ip), "D" 
                                 (TASK[PID].THREAD.SP) /* input C or D mean%ecx/%edx*/);   
                                       

In combination with code comments, it can be concluded that 36 lines of code initialize the PCB of process No. 0, and set the processes to runnable, and the execution entry is set to My_process in a 36-line loop, which is initialized with 1 2 3rd, set to Unrunnable, and 0 The next pointer of 1 2 3rd process is set to the address of 1 2 3 0 respectively (form a single loop linked list) and set the respective THREAD.SP pointers to the starting address of their respective kernel stacks. Then in the assembly code of L48 to L55, the current ESP is set to TASK[0].THREAD.SP, which is incorporated into the stack save,
The My_process function at the Thread.ip address of process No. 0 is then indirectly push/ret by means of the method. followed by the pop %ebp first executed code of the next scheduled process

To the My_process function, each cycle 10000000 thereafter, first Judge My_need_sched, if the previous My_timer_handler will my_need_schedule 1 (every 1000 clock interrupt), then enter My_ Schedule and put my_need_sched 0;

Now is the time to dispatch the My_schedule function:
If Next process executes for the first time (state = =-1), the process in the Else branch is pressed:
Into the stack ebp, save the current ESP to PREV->THREAD.SP, EIP to Prev->thread.ip, then set EBP, esp to NEXT->THREAD.SP, and then the same method as the No. 0 process (push Thread.ip; RET) to call the My_process function.

If Next process is dispatched again (state = = 0), it is executed in rows 56 through 69.

Summary: The implementation of the scheduling needs to save the current task/process field (EBP/EIP), and then with the clock interrupt, for the first time to be dispatched and again by the scheduling of the situation processing.

Linux kernel Design second week Learning summary complete a simple time slice rotation multi-channel program kernel code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.