[solved]-Assignment Schedule Handling C Systemcallh Include Include Include Include Define Systemca Q39025194
assignment with schedule handling in C
———————————systemcall.h——————————–
#include
#include
#include
#include
#define systemcall(x) {
errno = 0;
(x);
int err = errno;
if (err) {
fprintf(stderr, “In file %s at line %d: “, __FILE__, __LINE__);
perror(#x);
exit(err);}
}
errno = 0;
#define WRITESTRING(STRING)
systemcall(write(STDOUT_FILENO, STRING, strlen(STRING)));
int eye2eh(int i, char *buffer, int buffersize, int base);
#define WRITEINT(INT, LEN) { char buf[LEN];
eye2eh(INT, buf, LEN, 10); WRITESTRING(buf); }
—————————–count2five.sh———————————–
#! /bin/bash
for i in {1..5}
do
echo “Process $$ $i”
sleep 1
done
exit 5
—————————————-eye2eh.c—————————————–
#include
#include
#include
#include
#include
#include “systemcall.h”
/*
** Async-safe integer to a string. i is assumed to be positive.The number
** of characters converted is returned; -1 will be returned ifbuffersize is
** less than one or if the string isn’t long enough to hold theentire
** number. Numbers are right justified. The base must be between2 and 16;
** otherwise the string is filled with spaces and -1 isreturned.
*/
int eye2eh(int i, char *buffer, int buffersize, int base) {
if(buffersize <= 1 || base < 2 || base > 16) {
errno = EINVAL;
return(-1);
}
buffer[buffersize-1] = ”;
int count = 0;
const char *digits = “0123456789ABCDEF”;
for (int j = buffersize-2; j >= 0; j–) {
if (i == 0 && count != 0) {
buffer[j] = ‘ ‘;
}
else {
buffer[j] = digits[i%base];
i = i/base;
count++;
}
}
if (i != 0) {
errno = EINVAL;
return(-1);
}
errno = 0;
return(count);
}
#ifdef UNITTESTEYE2EH
#define BUFFERLEN 5
int main() {
char buffer[BUFFERLEN];
// not enough room
assert(eye2eh (1, buffer, 1, 10) == -1);
assert(errno == EINVAL);
assert(eye2eh (12345, buffer, BUFFERLEN, 10) == -1);
assert(errno == EINVAL);
// bad base
assert(eye2eh (1, buffer, BUFFERLEN, 1) == -1);
assert(errno == EINVAL);
assert(eye2eh(1, buffer, BUFFERLEN, 10) == 1);
assert(strncmp(buffer, ” 1″, BUFFERLEN) == 0);
assert(eye2eh (10, buffer, BUFFERLEN, 10) == 2);
assert(strncmp(buffer, ” 10″, BUFFERLEN) == 0);
assert(eye2eh (12, buffer, BUFFERLEN, 10) == 2);
assert(strncmp(buffer, ” 12″, BUFFERLEN) == 0);
assert(eye2eh (1234, buffer, BUFFERLEN, 10) == 4);
assert(strncmp(buffer, “1234”, BUFFERLEN) == 0);
assert(eye2eh (6, buffer, BUFFERLEN, 2) == 3);
assert(strncmp(buffer, ” 110″, BUFFERLEN) == 0);
assert(eye2eh (6, buffer, BUFFERLEN, 16) == 1);
assert(strncmp(buffer, ” 6″, BUFFERLEN) == 0);
assert(eye2eh (12, buffer, BUFFERLEN, 16) == 1);
assert(strncmp(buffer, ” C”, BUFFERLEN) == 0);
assert(eye2eh (12, buffer, BUFFERLEN, 8) == 2);
assert(strncmp(buffer, ” 14″, BUFFERLEN) == 0);
assert(eye2eh (0, buffer, BUFFERLEN, 10) == 1);
assert(strncmp(buffer, ” 0″, BUFFERLEN) == 0);
}
#endif
————————————CPU.c THE ASSIGNMENT IS INCOMMENT———————————–
#include
#include
#include
#include
#include
#include
#include
#include
#include “systemcall.h”
/*
This program does the following.
1) Creates handlers for two signals.
2) Create an idle process which will be executed when there isnothing
else to do.
3) Create a send_signals process that sends a SIGALRM every sooften.
The output looks approximately like:
[…]
Sending signal: 14 to process: 35050
Stopping: 35052
—- entering scheduler
Continuing idle: 35052
—- leaving scheduler
Sending signal: 14 to process: 35050
at the end of send_signals
Stopping: 35052
—- entering scheduler
Continuing idle: 35052
—- leaving scheduler
—- entering process_done
Timer died, cleaning up and killing everything
Terminated: 15
—————————————————————————
Add the following functionality.
1) Change the NUM_SECONDS to 20.
2) Take any number of arguments for executables and place eachon the
processes list with a state of NEW. The executables will notrequire
arguments themselves.
3) When a SIGALRM arrives, scheduler() will be called; itcurrently simply
restarts the idle process. Instead, do the following.
a) Update the PCB for the process that was interrupted includingthe
number of context switches and interrupts it had and changingits
state from RUNNING to READY.
b) If there are any NEW processes on processes list, change itsstate to
RUNNING, and fork() and execl() it.
c) If there are no NEW processes, round robin the processes inthe
processes queue that are READY. If no process is READY inthe
list, execute the idle process.
4) When a SIGCHLD arrives notifying that a child has exited,process_done() is
called.
a) Add the printing of the information in the PCB including thenumber
of times it was interrupted, the number of times it wascontext
switched (this may be fewer than the interrupts if a process
becomes the only non-idle process in the ready queue), and thetotal
system time the process took.
b) Change the state to TERMINATED.
c) Restart the idle process to use the rest of the timeslice.
*/
#define NUM_SECONDS 20
#define ever ;;
enum STATE { NEW, RUNNING, WAITING, READY, TERMINATED, EMPTY};
struct PCB {
enum STATE state;
const char *name; // name of the executable
int pid; // process id from fork();
int ppid; // parent process id
int interrupts; // number of times interrupted
int switches; // may be < interrupts
int started; // the time this process started
};
typedef enum { false, true } bool;
#define PROCESSTABLESIZE 10
struct PCB processes[PROCESSTABLESIZE];
struct PCB idle;
struct PCB *running;
int sys_time;
int timer;
struct sigaction alarm_handler;
struct sigaction child_handler;
void bad(int signum) {
WRITESTRING(“bad signal: “);
WRITEINT(signum, 4);
WRITESTRING(“n”);
}
// cdecl> declare ISV as array 32 of pointer to function(int)returning void
void(*ISV[32])(int) = {
/* 00 01 02 03 04 05 06 07 08 09 */
/* 0 */ bad, bad, bad, bad, bad, bad, bad, bad, bad, bad,
/* 10 */ bad, bad, bad, bad, bad, bad, bad, bad, bad, bad,
/* 20 */ bad, bad, bad, bad, bad, bad, bad, bad, bad, bad,
/* 30 */ bad, bad
};
void ISR (int signum) {
if (signum != SIGCHLD) {
kill (running->pid, SIGSTOP);
WRITESTRING(“Stopping: “);
WRITEINT(running->pid, 6);
WRITESTRING(“n”);
}
ISV[signum](signum);
}
void send_signals(int signal, int pid, int interval, int number){
for(int i = 1; i <= number; i++) {
sleep(interval);
WRITESTRING(“Sending signal: “);
WRITEINT(signal, 4);
WRITESTRING(” to process: “);
WRITEINT(pid, 6);
WRITESTRING(“n”);
systemcall(kill(pid, signal));
}
WRITESTRING(“At the end of send_signalsn”);
}
void create_handler(int signum, struct sigaction action,void(*handler)(int)) {
action.sa_handler = handler;
if (signum == SIGCHLD) {
action.sa_flags = SA_NOCLDSTOP | SA_RESTART;
} else {
action.sa_flags = SA_RESTART;
}
systemcall(sigemptyset(&action.sa_mask));
systemcall(sigaction(signum, &action, NULL));
}
void scheduler (int signum) {
WRITESTRING(“—- entering schedulern”);
assert(signum == SIGALRM);
WRITESTRING (“Continuing idle: “);
WRITEINT (idle.pid, 6);
WRITESTRING (“n”);
running = &idle;
idle.state = READY;
systemcall (kill (idle.pid, SIGCONT));
WRITESTRING(“—- leaving schedulern”);
}
void process_done (int signum) {
WRITESTRING(“—- entering process_donen”);
assert (signum == SIGCHLD);
WRITESTRING (“Timer died, cleaning up and killingeverythingn”);
systemcall(kill(0, SIGTERM));
WRITESTRING (“—- leaving process_donen”);
}
void boot()
{
sys_time = 0;
ISV[SIGALRM] = scheduler;
ISV[SIGCHLD] = process_done;
create_handler(SIGALRM, alarm_handler, ISR);
create_handler(SIGCHLD, child_handler, ISR);
assert((timer = fork()) != -1);
if (timer == 0) {
send_signals(SIGALRM, getppid(), 1, NUM_SECONDS);
exit(0);
}
}
void create_idle() {
idle.state = READY;
idle.name = “IDLE”;
idle.ppid = getpid();
idle.interrupts = 0;
idle.switches = 0;
idle.started = sys_time;
assert((idle.pid = fork()) != -1);
if (idle.pid == 0) {
systemcall(pause());
}
}
int main(int argc, char **argv) {
boot();
create_idle();
running = &idle;
for(ever) {
pause();
}
/*for (argc){
processes[].nameargv[]
processes.[].state = new
for compiling cpu executable
gcc -Wall -o CPU CPU.c eye2eh.c
} */
}
Expert Answer
Answer to assignment with schedule handling in C ———————————systemcall.h——————————– #in… . . .
OR