-
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
- How many process switches does the above CPU-bound process make during 3 minutes' execution?
- How many process switches does the above I/O-bound process make during 3 minutes' execution?
- How long is the CPU bound process idle during the 3 minutes' execution.
- 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:
- 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;
- You can add some code at function copy_process() or copy_thread() to set the initial values of the above four fields as 0.
- 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.
- 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.
- Inside the kernel, you could call do_gettimeofday() to get a microsecond-resolution timestamp, or getnstimeofday() for nanosecond resolution.
- 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
Last active
October 19, 2015 08:01
-
-
Save ShawnHuang/30b3b3afef863f7a193b to your computer and use it in GitHub Desktop.
Linux project II
Author
ShawnHuang
commented
Jan 2, 2015
目前結果!!!!
看似很OK..應該吧
明天寫另一支來確定 context_switch 次數會變動的時間總計是 3m,整理好再放上來
samou@samou-Aspire-5750:~/Project_02$ sh test
cpu_bound pid: 6817
io_bound pid : 6821
The CPU-bound process has made 153823 process switches
This process has idle 417748l usecs
The IO-bound process has made 671775 process switches
This process has idle 121624865l usecs
samou@samou-Aspire-5750:~/Project_02$ ./test_process_switch_ori 6817 6821
The CPU-bound process has made 153823 process switches
This process has idle 417748l usecs
The IO-bound process has made 671775 process switches
This process has idle 121624865l usecs
samou@samou-Aspire-5750:~/Project_02$ ./test_process_switch_ori 6817 6821
The CPU-bound process has made 153823 process switches
This process has idle 417748l usecs
The IO-bound process has made 671775 process switches
This process has idle 121624865l usecs
samou@samou-Aspire-5750:~/Project_02$
include/linux/sched.h
// add in struct
unsigned int cs_count;
unsigned long long during_time;
struct timeval idle_time, time_value;
// for system call
struct process_switch_info
{
unsigned int counter_cpu, counter_IO;
// for test 3min
unsigned long long cpu_during, io_during;
struct timeval time_cpu, time_IO;
};
kernel/fork.c
// init the valus we add
p->cs_count = 0;
p->during_time = 0;
p->idle_time.tv_sec = 0;
p->idle_time.tv_usec = 0;
p->time_value.tv_sec = 0;
p->time_value.tv_usec = 0;
kernel/sched/core.c
unsigned long long curtime;
struct timespec ts;
ktime_get_ts(&ts);
curtime = timespec_to_ns(&ts);
struct timeval cs_done;//now_value,future_value;
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;
}
context_switch(rq, prev, next); /* unlocks the rq */
/*
* The context switch have flipped the stack from under us
* and restored the local variables which were saved when
* this task called schedule() in the past. prev == current
* is still correct, but it can be moved to another cpu/rq.
*/
do_gettimeofday(&cs_done);
// record the time which prev process turn to sleep
prev->idle_time.tv_sec = cs_done.tv_sec;
prev->idle_time.tv_usec = cs_done.tv_usec;
ktime_get_ts(&ts);
curtime = timespec_to_ns(&ts);
temp = (next->start_time.tv_sec * 1000000000 + next->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 (next->idle_time.tv_sec != 0 && next->idle_time.tv_usec != 0)
if (prev->cs_count > 1) {
next->time_value.tv_sec += cs_done.tv_sec - next->idle_time.tv_sec;
next->time_value.tv_usec += cs_done.tv_usec - next->idle_time.tv_usec;
}
if (prev->during_time == 0)
prev->during_time = temp - curtime;
}
// 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