Skip to content

Instantly share code, notes, and snippets.

@firas-jolha
Last active October 15, 2023 13:58
Show Gist options
  • Save firas-jolha/538b705fead7ece3f66947842258972c to your computer and use it in GitHub Desktop.
Save firas-jolha/538b705fead7ece3f66947842258972c to your computer and use it in GitHub Desktop.
os-lab06-2023
idx at bt
0 5 2
1 7 6
2 20 3
3 3 8
4 2 4
5 3 1
6 10 6
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/time.h>
#define PS_MAX 10
// holds the scheduling data of one process
typedef struct{
int idx; // process idx (index)
int at, bt, rt, wt, ct, tat; // arrival time, burst time, response time, waiting time, completion time, turnaround time.
int burst; // remaining burst (this should decrement when the process is being executed)
} ProcessData;
// the idx of the running process
int running_process = -1; // -1 means no running processes
// the total time of the timer
unsigned total_time; // should increment one second at a time by the scheduler
// data of the processes
ProcessData data[PS_MAX]; // array of process data
// array of all process pids
pid_t ps[PS_MAX]; // zero valued pids - means the process is terminated or not created yet
// size of data array
unsigned data_size;
void read_file(FILE* file){
// TODO: extract the data of processes from the {file}
// and store them in the array {data}
// initialize ps array to zeros (the process is terminated or not created yet)
}
// send signal SIGCONT to the worker process
void resume(pid_t process) {
// TODO: send signal SIGCONT to the worker process if it is not in one of the states
// (1.not created yet or 2.terminated)
}
// send signal SIGTSTP to the worker process
void suspend(pid_t process) {
// TODO: send signal SIGTSTP to the worker process if it is not in one of the states
// (1.not created yet or 2.terminated)
}
// send signal SIGTERM to the worker process
void terminate(pid_t process) {
// TODO: send signal SIGTERM to the worker process if it is not in one of the states
// (1.not created yet or 2.terminated)
}
// create a process using fork
void create_process(int new_process) {
// TODO: stop the running process
// TODO: fork a new process and add it to ps array
// TODO: Now the idx of the running process is new_process
// TODO: The scheduler process runs the program "./worker {new_process}"
// using one of the exec functions like execvp
}
// find next process for running
ProcessData find_next_process() {
// location of next process in {data} array
int location = 0;
for(int i=0; i < data_size; i++) {
// TODO: find location of the next process to run from the {data} array
// Considering the scheduling algorithm FCFS
}
// if next_process did not arrive so far,
// then we recursively call this function after incrementing total_time
if(data[location].at > total_time){
printf("Scheduler: Runtime: %u seconds.\nProcess %d: has not arrived yet.\n", total_time, location);
// increment the time
total_time++;
return find_next_process();
}
// return the data of next process
return data[location];
}
// reports the metrics and simulation results
void report(){
printf("Simulation results.....\n");
int sum_wt = 0;
int sum_tat = 0;
for (int i=0; i< data_size; i++){
printf("process %d: \n", i);
printf(" at=%d\n", data[i].at);
printf(" bt=%d\n", data[i].bt);
printf(" ct=%d\n", data[i].ct);
printf(" wt=%d\n", data[i].wt);
printf(" tat=%d\n", data[i].tat);
printf(" rt=%d\n", data[i].rt);
sum_wt += data[i].wt;
sum_tat += data[i].tat;
}
printf("data size = %d\n", data_size);
float avg_wt = (float)sum_wt/data_size;
float avg_tat = (float)sum_tat/data_size;
printf("Average results for this run:\n");
printf(" avg_wt=%f\n", avg_wt);
printf(" avg_tat=%f\n", avg_tat);
}
void check_burst(){
for(int i = 0; i < data_size; i++)
if (data[i].burst > 0)
return;
// report simulation results
report();
// terminate the scheduler :)
exit(EXIT_SUCCESS);
}
// This function is called every one second as handler for SIGALRM signal
void schedule_handler(int signum) {
// increment the total time
total_time++;
/* TODO
1. If there is a worker process running, then decrement its remaining burst
and print messages as follows:
"Scheduler: Runtime: {total_time} seconds"
"Process {running_process} is running with {data[running_process].burst} seconds left"
1.A. If the worker process finished its burst time, then the scheduler should terminate
the running process and prints the message:
"Scheduler: Terminating Process {running_process} (Remaining Time: {data[running_process].burst})"
then the scheduler waits for its termination and there will be no running processes anymore.
Since the process is terminated, we can calculate its metrics {ct, tat, wt}
2. After that, we need to find the next process to run {next_process}.
// this call will check the bursts of all processes
check_burst();
3. If {next_process} is not running, then we need to check the current process
3.A. If the current process is running, then we should stop the current running process
and print the message:
"Scheduler: Stopping Process {running_process} (Remaining Time: {data[running_process].burst})"
3.B. set current process {next_process} as the running process.
3.C.1. then create a new process for {running_process} and print the message:
"Scheduler: Starting Process {running_process} (Remaining Time: {data[running_process].burst})"
Here we have the first response to the process {running_process} and we can calculate the metric {rt}
3.C.2. or resume the process {running_process} if it is stopped and print the message:
"Scheduler: Resuming Process {running_process} (Remaining Time: {data[running_process].burst})"
*/
}
int main(int argc, char *argv[]) {
// read the data file
FILE *in_file = fopen(argv[1], "r");
if (in_file == NULL) {
printf("File is not found or cannot open it!\n");
exit(EXIT_FAILURE);
} else {
read_file(in_file);
}
// set a timer
struct itimerval timer;
// the timer goes off 1 second after reset
timer.it_value.tv_sec = 1;
timer.it_value.tv_usec = 0;
// timer increments 1 second at a time
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 0;
// this counts down and sends SIGALRM to the scheduler process after expiration.
setitimer(ITIMER_REAL, &timer, NULL);
// register the handler for SIGALRM signal
signal(SIGALRM, schedule_handler);
// Wait till all processes finish
while(1); // infinite loop
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <stdbool.h>
// 6 digits for big triangular numbers like 113050
#define TRI_BASE 1000000
// current process pid (which executed this program)
pid_t pid;
// current process idx (starts from 0)
int process_idx;
// number of triangular numbers found so far
long tris;
bool is_triangular(long n){
for (long i = 1; i <= n; i++){
if (i * (i + 1) == 2 * n){
return true;
}
}
return false;
}
void signal_handler(int signum){
// print info about number of triangulars found.
printf("Process %d (PID=<%d>): count of triangulars found so far is \e[0;31m%ld\e[0m\n", process_idx, pid, tris);
switch(signum) {
case SIGTSTP:
// pause the process indefinitely
printf("Process %d: stopping....\n", process_idx);
pause();
break;
case SIGCONT:
// continue the process
printf("Process %d: resuming....\n", process_idx);
break;
case SIGTERM:
// terminate the process
printf("Process %d: terminating....\n", process_idx);
exit(EXIT_SUCCESS);
break;
default:
break;
}
}
// generates a big number n
long big_n() {
time_t t;
long n = 0;
srand((unsigned) time(&t));
while(n < TRI_BASE)
n += rand();
return n % TRI_BASE;
}
int main(int argc, char *argv[]){
// TODO: get the process_idx from argv
// process idx
process_idx = ....
pid = getpid();
// TODO: register the signals
long next_n = big_n() +1;
// The first message after creating the process
printf("Process %d (PID=<%d>): has been started\n", process_idx, pid);
printf("Process %d (PID=<%d>): will find the next trianguar number from [%ld, inf)\n", process_idx, pid, next_n);
// initialize counter
tris = 0;
while (true){
// TODO: in an infinite loop, search for next triangular numbers starting from {next_n}
// Every time you find a new triangular number print the message:
// "Process {process_idx} (PID=<{pid}>): I found this triangular number \e[0;31m{next_n}\e[0m\n"
// and increase the count {tris}
next_n++;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment