Analysis of process start-up and process switching mechanism through a simple time slice rotation multi-channel program

Source: Internet
Author: User
Tags volatile

remark: Autumn Wind + original works reproduced please specify the source + "Linux kernel analysis" MOOC course http://mooc.study.163.com/course/USTC-1000029000

1. After configuring the environment, start the kernel with the QEMU emulator and run the following:

650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/5B/47/wKioL1UFP0Tj3LtcAAMY50auwu8291.jpg "title=" Qq20150314094250.png "alt=" Wkiol1ufp0tj3ltcaamy50auwu8291.jpg "/>

650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/5B/4D/wKiom1UFPgbi_ByoAAIc3oq_5lo273.jpg "style=" float: none; "title=" Qq20150314094811.png "alt=" Wkiom1ufpgbi_byoaaic3oq_5lo273.jpg "/>

2. Realize the source code of time slice rotation multi-Channel program Dispatch:

Mymain.c

/* *  linux/mykernel/mymain.c * *  kernel internal my_start_ kernel * *  copyright  (C)  2013  mengning * */#include   <linux/types.h> #include  <linux/string.h> #include  <linux/ctype.h> #include  < linux/tty.h> #include  <linux/vmalloc.h> #include   "Mypcb.h" TPCB&NBSP;TASK[MAX_TASK_NUM];TPCB  * my_current_task = null;volatile int my_need_sched = 0;void my_ Process (void); Void __init my_start_kernel (void) {    int pid = 0;     int i;    /* Initialize process 0*/     task[pid].pid = pid;    task[pid].state = 0;/*  -1 unrunnable, 0 runnable, >0 stopped */    task[pid]. Task_entry = task[pid].thread.ip =  (Unsigned long) my_process;    task[pid].thread.sp =   (Unsigned long) &task[pid].stack[kernel_stack_size-1];    task[pid].next  = &task[pid];    /*fork more process */     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 =  (Unsigned long) &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*/);}    void my_Process (void) {    int i = 0;    while (1)      {        i++;         if (i%10000000 == 0)         {     &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (kern_notice  "this is process %d  -\n ", my_current_task->pid);             if (my_need_sched == 1)             {                 my_need_sched =  0;            my_schedule ();   &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;}&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (KERN_NOTICE  " This is process&nBsp;%d +\n ", My_current_task->pid);        }          }}

 mybcp.h

/* *  linux/mykernel/mypcb.h * *  kernel internal pcb types  * *  Copyright  (C)  2013  mengning * */#define  max_task _num        4#define kernel_stack_size   1024*8/*  CPU-specific state of this task */struct Thread {     unsigned longip;    unsigned longsp;}; Typedef struct pcb{    int pid;    volatile long  state;/* -1 unrunnable, 0 runnable, >0 stopped */     char stack[kernel_stack_size];    /* cpu-specific state of  this task */    struct Thread thread;     unsigned longtask_entry;    struct&nbsp Pcb *next;} Tpcb;void my_schedule (void);

 myinterrupt.c

/* *  linux/mykernel/myinterrupt.c * *  kernel internal my_timer_ handler * *  copyright  (C)  2013  mengning * */#include   <linux/types.h> #include  <linux/string.h> #include  <linux/ctype.h> #include  < linux/tty.h> #include  <linux/vmalloc.h> #include   "Mypcb.h" Extern tpcb task[max_task _num];extern tpcb * my_current_task;extern volatile int my_need_sched;volatile  int time_count = 0;/* * Called by timer interrupt. *  It runs in the name of current running process, * so it  use kernel stack of current running process */void my_timer_ Handler (void) {#if  1    if (time_count%100 == 0 && my_need_ Sched != 1) &NBSP;&NBSP;&NBSP;&NBSP;{&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (KERN_NOTICE  ">> >my_timer_handler here<<<\n ");         my_need_sched  = 1;    }     time_count ++ ;  # Endif    return;  }void my_schedule (void) {&NBSP;&NBSP;&NBSP;&NBSP;TPCB  * next;    tpcb * prev;    if (My_current_task  == null         | |  my_current_task->next == null)     {    return; &NBSP;&NBSP;&NBSP;&NBSP;}&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (kern_notice  ">>>my_schedule<<<\ n ");     /* schedule */    next = my_current_task- >next;    prev = my_current_task;     if (next->state == 0)/* -1 unrunnable, 0 runnable,  >0 stopped */    {    /* switch to  Next process */    asm volatile (          "Pushl %%ebp\n\t"      /* save ebp */          "movl %%esp,%0\n\t"  /* save esp */          "movl %2,%%esp\n\t"      /* restore   esp */         "movl $1f,%1\n\t"         /* save eip */         "PUSHL  %3\n\t "         " ret\n\t "              /* restore  eip */         "1:\t"                    /*  next process start here */         "POPL&NBSP;%%EBP \n\t "        : " =m "  (PREV-&GT;THREAD.SP)," =m "  (prev- &GT;THREAD.IP)         :  "M"   (NEXT-&GT;THREAD.SP), "M"   ( NEXT-&GT;THREAD.IP)     );     my_current_task = next; &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (kern_notice  ">>>switch %d to %d<<<\ n ", Prev->pid,next->pid);       }    else     {        next->state = 0;       &NBSP;&NBSP;MY_CURRENT_TASK&NBSP;=&NBSP;NEXT;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;PRINTK (KERN_NOTICE   ">>>switch %d to %d<<<\n", Prev->pid,next->pid);     /* switch to new process */    asm volatile (          "pushl %%ebp\n\t"      /* save  ebp */         "movl %%esp,%0\n\t"  /* save  esp */         "movl %2,%%esp\n\t"       /* restore  esp */         "movl % 2,%%ebp\n\t "     /* restore  ebp */          "movl $1f,%1\n\t"        /* save eip * /         "pushl %3\n\t"           "ret\n\t"              /* restore  eip  */        :  "=m"   (PREV-&GT;THREAD.SP), "=m"   (prev- &GT;THREAD.IP)         :  "M"   (NEXT-&GT;THREAD.SP), "M"   ( NEXT-&GT;THREAD.IP)     );               }       return;}


3. Process start-up and switching mechanism

The operating system manages the process management schedule mainly through the Process Control block (PCB)

typedef struct pcb{int pid;    Volatile long state;/*-1 unrunnable, 0 runnable, >0 stopped */char stack[kernel_stack_size];    /* Cpu-specific State of the This task */struct thread thread;    unsigned longtask_entry; struct PCB *next;} TPCB;

When the kernel starts, in the void __init my_start_kernel (void) function, 4 processes are generated first, and the first process in the process queue is passed through a statement

Task[pid].task_entry = Task[pid].thread.ip = (unsigned long) my_process;

is set to My_process, and the process is process No. 0, after which 3 processes pass Task[i].next = Task[i-1].next; the statements are all my_process.

After entering the respective process, according to My_need_sched to determine the running state of the process and scheduling, this state in the My_timer_handler function according to the timing situation set, once the time is satisfied will generate interrupt notification process, the process to do the corresponding operation.

The process state is determined when an interrupt is generated, if next->state = = 0, the next process can be run, then the code is compiled by

    asm volatile (         "pushl %%ebp\n\ T "     /* save ebp */        " Movl %%esp,%0\n\t " /* save esp */        " Movl %2,%%esp\n\t "     /* restore  esp */          "movl $1f,%1\n\t"        /* save  eip */         "pushl %3\n\t"            "ret\n\t"               /* restore  eip */         "1:\t"                    /*  Next process start here */         "popl %%ebp\n\t"          :  "=m"   (PREV-&GT;THREAD.SP), "=m"   (PREV-&GT;THREAD.IP)          :  "M"   (NEXT-&GT;THREAD.SP), "M"   (NEXT-&GT;THREAD.IP)      );

Saves the execution environment of the current process to the stack and moves to the end of the process queue, loads the next IP that is in progress, and starts executing the next process.

If the status of the next process is not executable, set it to the executable state ready to accept the schedule, save its current execution environment and move to the tail of the process queue and return. The NO. 0 process then executes the executable process in the scheduling process queue.


4. Summary:

In the process scheduling algorithm of the time slice rotation multi-channel program, the time slice is determined by the timer, and the time slice is rotated by the interrupt. The process scheduling is done in a simple sequential way through the process queue.

This article is from "Whispering Autumn Wind" blog, please be sure to keep this source http://xjhznick.blog.51cto.com/3608584/1620535

Analysis of process start-up and process switching mechanism through a simple time slice rotation multi-channel program

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.