Skip to content

Instantly share code, notes, and snippets.

@ShawnHuang
Last active October 19, 2015 08:01
Show Gist options
  • Save ShawnHuang/30b3b3afef863f7a193b to your computer and use it in GitHub Desktop.
Save ShawnHuang/30b3b3afef863f7a193b to your computer and use it in GitHub Desktop.
Linux project II
  • Score: 115 points.

  • Description:

    • Write a CPU-bound program cpu_bound.c as follows:

             #include <stdio.h>
             main()
             {
                int  a;
      
                while(1)
                  ++a;
             }
      
    • Write an I/O-bound program io_bound.c as follows:

             #include <stdio.h>
             main()
             {
               FILE  *out;
               char  c;
               int   a;
      
               while(1)
               {
                 for(a=0;a>0;)
                   ++a;
      
                if((out=fopen("io_bound.data","w"))!=NULL)
                {
                  c=38;
                  for(a=0; a<10000;a++)
                  {
                    putc(c,out);
                    if(++c>126)
                      c=38;
                  }
                  fclose(out);
                }
                else
                {
                  printf("Cannot open file.\n");
                  exit(0);
                }
               }
             }
      
    • Execute the above two programs in background.

    • Change the kernel so that you can utilize a new system call to learn

      1. How many process switches does the above CPU-bound process make during 3 minutes' execution?
      2. How many process switches does the above I/O-bound process make during 3 minutes' execution?
      3. How long is the CPU bound process idle during the 3 minutes' execution.
      4. How long is the I/O bound process idle during the 3 minutes' execution.
    • Write a program test_process_switch.c as follows to test your new kernel. The program accepts two parameters. The first parameter is the PID of the above CPU-bound process. The second parameter is the PID of the above I/O bound process.

              #include <stdio.h>
              #include <unistd.h>
              #include <stdlib.h>
      
              struct process_switch_info
              {
                unsigned int   counter_cpu, counter_IO;
                struct timeval time_cpu, time_IO;
              };
      
      
              main(int argc, char **argv)
              {
                int                        pid_cpu,pid_IO;
                unsigned long              temp_ul;
                struct process_switch_info ps_info;
      
                
                if(argc<3)
                {
                  printf("Input the PIDs of the CPU-bound process and I/O-bound process as the parameters of this executable.\n");
                  printf("Format: program pid_cpu pid_IO\n");
                  exit(0);
                }
      
                pid_cpu=atoi(argv[1]);
                pid_IO=atoi(argv[2]);
      
                get_process_switch_info(&ps_info,pid_cpu,pid_IO);    //new system call
                /*===========================================================================*/
                /*     prototype of the new system call is as follows                        */
                /*     void get_process_switch_info(struct process_switch_info *, int, int)  */
                /*===========================================================================*/
                temp_ul=(ps_info.time_cpu.tv_sec * 1000000 + ps_info.time_cpu.tv_usec);
                printf("The CPU-bound process has made %ld process switches\n", ps_info.counter_cpu);
                printf("This process has idle %ul usecs\n", temp_ul); 
      
                temp_ul=(ps_info.time_IO.tv_sec * 1000000 + ps_info.time_IO.tv_usec);
                printf("The IO-bound process has made %ld process switches\n", ps_info.counter_IO);
                printf("This process has idle %ul usecs\n", temp_ul); 
              }
      
    • Hint:

      1. You may need to add some fields in the END of the struct task_struct to record related info. The initial values of these fields are 0;
      2. You can add some code at function copy_process() or copy_thread() to set the initial values of the above four fields as 0.
      3. Each time when the schedule() makes a process switch from process 1 to process 2, you need to add the number of process switches of process 2 by 1.
      4. Each time when schedule() makes a process switch from process 1 to process 2, process 1 begins idle until next time schedule() makes a process switch to give CPU control to process 1 again. During the exectuiont of a process, the process may experience process switch several times. Hence the total idle time of a process is the sum of all the above individual idle time.
      5. Inside the kernel, you could call do_gettimeofday() to get a microsecond-resolution timestamp, or getnstimeofday() for nanosecond resolution.
      6. You may need to add a new system call to do project 2.
      • Check the "Referenced Material" part of the Course web site to see how to add a new system call in Linux.
  • Project Submission:

    • The due day of reports submission is 17th Jan. 2015
    • The demo will be held on 19th Jan. 2015, 20th Jan. 2015, and 21st Jan. 2015
    • Contact the TAs to choose your demo time before 16thd Jan. 2015
    • On site demo of this project is required.
    • When demonstrating your projects, the TAs will ask you some questions regarding to your projects. Part of your project grade is determined by your answers to the questions.
    • You need to submit both an electronic version and a hard-copy of your project report to the TAs.
      • The electronic versions could be sent to the TAs through e-mails.
      • Do not forget writing the names and student IDs of all members in your team.
      • Your report should contain:
        • Your source code
        • the execution results
    • Late submission
Copy link

ghost commented Jan 15, 2015

    // get current time and convert to ns
    unsigned long long curtime;
    struct timespec ts;
    ktime_get_ts(&ts);
    curtime = timespec_to_ns(&ts);

    // save time when cs exec and cs done
    struct timeval cs_enter, cs_done;
    unsigned long long temp = (next->start_time.tv_sec * 1000000000 + next->start_time.tv_nsec + 180000000000);

    if (temp > curtime) {
        next->cs_count++;
        if (next->during_time == 0)
            next->during_time = temp - curtime;
    }

    do_gettimeofday(&cs_enter);
    // record the time when it zZZ
    prev->idle_time.tv_sec = cs_enter.tv_sec; 
    prev->idle_time.tv_usec = cs_enter.tv_usec;

    context_switch(rq, prev, next);

    do_gettimeofday(&cs_done);

    ktime_get_ts(&ts);
    curtime = timespec_to_ns(&ts);

    temp = (prev->start_time.tv_sec * 1000000000 + prev->start_time.tv_nsec + 180000000000);

    if((prev->start_time.tv_sec * 1000000000 + prev->start_time.tv_nsec + 180000000000) > curtime) {
        prev->cs_count++;
        // if next process had been sleep, we calc the time between it sleep and awake
        if (prev->cs_count > 1) { // don't calc sleeping time at first time 
            prev->sleep_time.tv_sec += cs_done.tv_sec - prev->idle_time.tv_sec;
            prev->sleep_time.tv_usec += cs_done.tv_usec - prev->idle_time.tv_usec;
        }
        if (prev->during_time == 0)
            prev->during_time = temp - curtime;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment