Question
C Programming Language Scheduler - Operating Systems Programming struct node { //Struct describing the node of the queue }; struct queue { //Struct describing the
C Programming Language Scheduler - Operating Systems Programming
struct node { //Struct describing the node of the queue }; struct queue { //Struct describing the queue };
void enqueue( . . . ){ . . . }
int dequeue( . . . ){ . . . }
void term child ( . . . ){ // Signal hanlder , the termination of a process . . . } int main( int argc , char const argv [ ] ) { . . . // Variable initialization . . . // Anything you need // PART 1: Parse arguments from the user i f ( argc >2) { qt = 1000atoi(&argv [ 1 ] [ 0 ] ) ; //Here you need the qt } else { printf (%s qt prog1 [ prog2 ] . . . [ prog [N} , argv [0]) ; exit (1) ; } . . . // Any other . . . // necessary code // PART 2: Forking the processes for ( . . . ) { printf (Message from father : Creating program %s , argv [ i ]) ; Fork , execl [ execl ( argv [ i ] , argv [ i ] ,NULL) ] processes and enqueue enqueue the process } sleep (1) ; // Small safe delay printf ( I am the Scheduler and I will now begin scheduling my programs : ) ; // PART 3: Scheduling loop while ( . . . ) //Scheduling loop 2 { send the signal SIGCONT to the f i r s t element in queue usleep ( qt ) ; i f ( child has not finished ) { send the signal SIGUSR1 to the f i r s t element in queue usleep (1000) ; // Small safe delay dequeue and reenqueue } else { printf (A child is dead ) ; remove from l i s t & mark child as dead } } }
Section 1 - Scheduler In this lab exercise, you are asked to design and implement a scheduler that follows different schedul- ing policies. Specifically, you need to develop a scheduler that creates N processes and schedules them in the following ways: 1. Round Robin:. Each process will be allowed to have access to the CPU for a time quantum (qt). After this time quantum is completed, the process should stop and the scheduler must select the next one. The qt must be equal for all processes and it will be defined by the user. The processes should be initialized and wait for the parent to send them a signal in order to be activated. Instructions for the Round Robin scheduler: The communication between the processes and the scheduler will be based on signals. We need 3 signals total. The first signal will be used in order to start a process (SIGCONT), while the second one will be used to stop it (SIGUSR1). The last signal, will be used to inform the scheduler that a child has finished its workload (SIGCHLD). The scheduler takes as arguments the qt and the names of the programs to execute. The first important thing is to fork() the children that will execute the programs. Obviously, the scheduler needs to save the PIDs of all of its children so as to be able to communicate with them. The qt is needed only for Round Robin and MFQ. The other scheduling policies just ignore it. A very reliable and easy to implement data structure for the Round Robin scheduling policy is the queue. Thus, when the scheduler creates a new process, it inserts the PID of that process into the queue. When all processes have been created, the scheduler needs to initialize all of them. After that, the scheduler starts the execution of the scheduling loop which is executed as long as processes exist in the queue. In the scheduling loop, the scheduler sends the SIGCONT signal to the fist process in the queue so to start/continue its execution. At the end of the qt, if the process has not completed its task, the scheduler sends the SIGUSR1 signal and puts it at the back of the queue. If the process completed its workload, it sends the SIGCHLD signal to the scheduler in order to be removed from the queue. Below, you can find a basic structure for the scheduler: struct node // Struct describing the node of the queue }; struct queue // Struct describing the queue void enqueue (...){ int dequeue (...){ void term-child(...){ // Signal hanlder, the termination of a process int main(int argc, char const *argv (1) . .. // Variable initialization // Anything you need // PART 1: Parse arguments from the user if (argc >2) qt = 1000*atoi(&argv [1][0]); // Here you need the qt else printf("%s qt progl (prog2] ... (prog (N} , argv[0]); exit(-1); } ... // Any other ... // necessary code // PART 2: Forking the processes for (...) printf(" Message from father: Creating program %s ", argv[i]); Fork, execl [execl (argv[i], argv[i] ,NULL)] processes and enqueue enqueue the process sleep (1); // Small safe delay printf(" I am the Scheduler and I will now begin scheduling my programs: "); // PART 3: Scheduling loop while (...) //Scheduling loop send the signal SIGCONT to the first element in queue usleep (qt); if (child has not finished) send the signal SIGUSR1 to the first element in queue usleep (1000); // Small safe delay dequeue and re-enqueue else printf("A child is dead n"); remove from list & mark child as dead Section 1 - Scheduler In this lab exercise, you are asked to design and implement a scheduler that follows different schedul- ing policies. Specifically, you need to develop a scheduler that creates N processes and schedules them in the following ways: 1. Round Robin:. Each process will be allowed to have access to the CPU for a time quantum (qt). After this time quantum is completed, the process should stop and the scheduler must select the next one. The qt must be equal for all processes and it will be defined by the user. The processes should be initialized and wait for the parent to send them a signal in order to be activated. Instructions for the Round Robin scheduler: The communication between the processes and the scheduler will be based on signals. We need 3 signals total. The first signal will be used in order to start a process (SIGCONT), while the second one will be used to stop it (SIGUSR1). The last signal, will be used to inform the scheduler that a child has finished its workload (SIGCHLD). The scheduler takes as arguments the qt and the names of the programs to execute. The first important thing is to fork() the children that will execute the programs. Obviously, the scheduler needs to save the PIDs of all of its children so as to be able to communicate with them. The qt is needed only for Round Robin and MFQ. The other scheduling policies just ignore it. A very reliable and easy to implement data structure for the Round Robin scheduling policy is the queue. Thus, when the scheduler creates a new process, it inserts the PID of that process into the queue. When all processes have been created, the scheduler needs to initialize all of them. After that, the scheduler starts the execution of the scheduling loop which is executed as long as processes exist in the queue. In the scheduling loop, the scheduler sends the SIGCONT signal to the fist process in the queue so to start/continue its execution. At the end of the qt, if the process has not completed its task, the scheduler sends the SIGUSR1 signal and puts it at the back of the queue. If the process completed its workload, it sends the SIGCHLD signal to the scheduler in order to be removed from the queue. Below, you can find a basic structure for the scheduler: struct node // Struct describing the node of the queue }; struct queue // Struct describing the queue void enqueue (...){ int dequeue (...){ void term-child(...){ // Signal hanlder, the termination of a process int main(int argc, char const *argv (1) . .. // Variable initialization // Anything you need // PART 1: Parse arguments from the user if (argc >2) qt = 1000*atoi(&argv [1][0]); // Here you need the qt else printf("%s qt progl (prog2] ... (prog (N} , argv[0]); exit(-1); } ... // Any other ... // necessary code // PART 2: Forking the processes for (...) printf(" Message from father: Creating program %s ", argv[i]); Fork, execl [execl (argv[i], argv[i] ,NULL)] processes and enqueue enqueue the process sleep (1); // Small safe delay printf(" I am the Scheduler and I will now begin scheduling my programs: "); // PART 3: Scheduling loop while (...) //Scheduling loop send the signal SIGCONT to the first element in queue usleep (qt); if (child has not finished) send the signal SIGUSR1 to the first element in queue usleep (1000); // Small safe delay dequeue and re-enqueue else printf("A child is dead n"); remove from list & mark child as dead
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started