Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

/* -------------------------- loader.c ----------------------- */ /* This is the shell for developing the loader cpu and printer */ /* for csc 389 project */ #include

image text in transcribed

/* -------------------------- loader.c ----------------------- */

/* This is the shell for developing the loader cpu and printer */

/* for csc 389 project */

#include

#include

#include

#include

#include

#include

#include

#include

#include "semshm.c"

#define NUM_OF_SEMS 8 /* the number of sems to create */

#define OK_TO_LOAD0 0

#define OK_TO_LOAD1 1

#define OK_TO_EXEC0 2

#define OK_TO_EXEC1 3

#define OK_TO_SET_OUTPUT0 4

#define OK_TO_SET_OUTPUT1 5

#define OK_TO_PRINT0 6

#define OK_TO_PRINT1 7

#define HOWMANY_PROCESSES 3

#define HOWMANY_JOBS 2

#define TRUE 1

#define FALSE 0

int my_semid, my_shrmemid; /* semaphore id and shared memory ids */

int my_key; /* key used to get shared memory */

int my_semval;

char *my_shrmemaddr; /* address of shared memory */

typedef struct _pcb

{int start_loc, num_instructions, output_loc;}

pcb_type;

typedef struct _mem

{char operation; int operand1, operand2, result;}

memory_type;

pcb_type *pcbs;

memory_type *memory;

int *load_job, *print_job,size_of_memory, s, i;

/* functions to be invoked later */

void P(); /* acquire semaphore */

void V(); /*release semaphore */

static void semcall(); /* call semop */

void init_sem(); /* initialize semaphores */

void remove_shrmem(); /* remove shared memory */

void remove_sem(); /* remove semaphores */

void driver(); /* driver for forking processes */

void loader();

void cpu();

void printer();

void execute_memory();

void print_memory();

int fill_memory();

main (int argc, char *argv[])

{ /* this program uses semaphores and shared memory. Semaphores are

used to protect the shared memory which serves as a message area

for and sender and receiver process */

int i ;

setbuf(stdout, NULL);

/* get semaphore id and a given number of semaphores */

if ((my_semid = semtran(NUM_OF_SEMS)) != -1)

{

/* initialize the semaphores */

init_sem(my_semid,OK_TO_LOAD0, 1);

init_sem(my_semid,OK_TO_LOAD1, 1);

init_sem(my_semid,OK_TO_EXEC0, 0);

init_sem(my_semid,OK_TO_EXEC1, 0);

init_sem(my_semid,OK_TO_SET_OUTPUT0, 1);

init_sem(my_semid,OK_TO_SET_OUTPUT1, 1);

init_sem(my_semid,OK_TO_PRINT0, 0);

init_sem(my_semid,OK_TO_PRINT1, 0);

}

/* get shared memory segement id and attach it to my_shrmemaddr */

size_of_memory = N*sizeof(*load_job) + 2*sizeof(*print_job) +

4*sizeof(*pcbs) + 40 * sizeof(*memory);

if ((get_attach_shrmem(size_of_memory,&my_shrmemaddr,&my_shrmemid)) != -1)

/* connect to shared memory at my_shrmemaddr */

load_job = (int *) my_shrmemaddr;

print_job = load_job + 2;

pcbs = (pcb_type *) (print_job + 2);

memory = (memory_type *) (pcbs + 4);

/* call driver to do the work of forking senders and receivers */

driver();

/* wait until all processes have completed their work */

for (i = 1; i

printf("The End. ");

remove_sem(my_semid); /* remove the semaphores */

remove_shrmem(my_shrmemid, my_shrmemaddr); /* remove the shared memory */

exit(0);

} /* end of main */

void driver() /* driver to fork processes to handle the work */

{

int pid;

if (( pid = fork() ) == -1) syserr("fork");

if ( pid == 0 )

{

loader();

exit(0);

}

if (( pid = fork() ) == -1) syserr("fork");

if ( pid == 0 )

{

cpu();

exit(0);

}

if (( pid = fork() ) == -1) syserr("fork");

if ( pid == 0 )

{

printer();

exit(0);

}

} /* end of driver */

void loader()

{

FILE *fid;

int memory_to_load, current_job, more_jobs, job_read;

if ((fid = fopen (inputfile, "r")) == 0)

{

puts ("Unable to open file for reading.");

exit(0);

}

more_jobs = 2;

current_job = 0;

while (more_jobs)

{

if (current_job == 0)

{

P(my_semid, OK_TO_LOAD0);

memory_to_load = 0;

pcbs[current_job].start_loc = 0;

pcbs[current_job].output_loc = 20;

pcbs[current_job].num_instructions = 0;

job_read = fill_memory(fid, memory_to_load);

if (job_read != 4)

{

more_jobs = more_jobs - 1;

load_job[current_job] = -1;

}

else

load_job[current_job] = 1;

V(my_semid, OK_TO_EXEC0);

}

else

{

P(my_semid, OK_TO_LOAD1);

memory_to_load = 10;

pcbs[current_job].start_loc = 10;

pcbs[current_job].output_loc = 30;

pcbs[current_job].num_instructions = 0;

job_read = fill_memory(fid, memory_to_load);

if (job_read != 4)

{

more_jobs = more_jobs - 1;

load_job[current_job] = -1;

}

else

load_job[current_job] = 1;

V(my_semid, OK_TO_EXEC1);

}

current_job = (current_job + 1) % 2;

} /* end while more_jobs */

fclose(fid);

return;

} /* end of load */

int fill_memory (FILE *fid, int memory_to_fill)

{

int opcode_ok, end_of_job, bad_instruction, operand1, operand2, elements_read, current_pcb;

char opcode, cr;

if (memory_to_fill == 0)

current_pcb = 0;

else

current_pcb = 1;

elements_read = TRUE;

end_of_job = FALSE;

while (elements_read )

{

elements_read = fscanf (fid, "%c %d %d%c", &opcode, &operand1, &operand2,&cr);

if (elements_read != 4)

{

return(elements_read);

}

else

{

switch (opcode)

{

case '+':

opcode_ok = TRUE;

break;

case '-':

opcode_ok = TRUE;

break;

case '*':

opcode_ok = TRUE;

break;

case '/':

opcode_ok = TRUE;

break;

case '%':

opcode_ok = TRUE;

break;

default :

if (opcode == '?')

{

bad_instruction = FALSE;

end_of_job = TRUE;

}

else

{

end_of_job = FALSE;

opcode_ok = FALSE;

bad_instruction = TRUE;

};

} /* end of switch */

} /* end of else elements read was 4 */

if (end_of_job == TRUE)

return(elements_read);

pcbs[current_pcb].num_instructions = pcbs[current_pcb].num_instructions + 1;

memory[memory_to_fill].operation = opcode;

memory[memory_to_fill].operand1 = operand1;

memory[memory_to_fill].operand2 = operand2;

memory_to_fill = memory_to_fill + 1;

} /* end of while for fill memory */

} /* end of fill memory */

void cpu()

{

int memory_to_execute, current_job, where_to_output, memory_to_output, more_jobs;

current_job = 0;

more_jobs = 2;

while (more_jobs)

{

if (current_job == 0)

{

P(my_semid, OK_TO_EXEC0);

if (load_job[current_job] == -1)

{

more_jobs = more_jobs -1;

P(my_semid, OK_TO_SET_OUTPUT0);

print_job[current_job] = -1;

V(my_semid, OK_TO_LOAD0);

V(my_semid, OK_TO_PRINT0);

}

else

{

execute_memory(current_job);

P(my_semid, OK_TO_SET_OUTPUT0);

pcbs[current_job + 2] = pcbs[current_job];

memory_to_output = pcbs[current_job + 2].start_loc;

where_to_output = pcbs[current_job + 2].output_loc;

for (i = 1; i

{

memory[where_to_output] = memory[memory_to_output];

memory_to_output = memory_to_output + 1;

where_to_output = where_to_output + 1;

}

load_job[current_job] = 0;

print_job[current_job] = 1;

V(my_semid, OK_TO_LOAD0);

V(my_semid, OK_TO_PRINT0);

} /* end for else for load job[current_job] != -1 */

}

else /* current_job != 0 */

{

P(my_semid, OK_TO_EXEC1);

if (load_job[current_job] == -1)

{

more_jobs = more_jobs -1;

P(my_semid, OK_TO_SET_OUTPUT1);

print_job[current_job] = -1;

V(my_semid, OK_TO_LOAD1);

V(my_semid, OK_TO_PRINT1);

}

else

{

execute_memory(current_job);

P(my_semid, OK_TO_SET_OUTPUT1);

pcbs[current_job + 2] = pcbs[1];

memory_to_output = pcbs[current_job + 2].start_loc;

where_to_output = pcbs[current_job + 2].output_loc;

for (i = 1; i

{

memory[where_to_output] = memory[memory_to_output];

memory_to_output = memory_to_output + 1;

where_to_output = where_to_output + 1;

}

load_job[current_job] = 0;

print_job[current_job] = 1;

V(my_semid, OK_TO_LOAD1);

V(my_semid, OK_TO_PRINT1);

} /* end for else for load job[1] != -1 */

}

current_job = (current_job + 1) % HOWMANY_JOBS;

} /* end while more jobs */

} /* end of cpu */

void execute_memory(int current_job)

{

int memory_to_execute, i;

if (current_job == 0)

memory_to_execute = 0;

else

memory_to_execute =10;

for ( i = 1; i

{

switch (memory[memory_to_execute].operation)

{

case '+':

memory[memory_to_execute].result =

memory[memory_to_execute].operand1 +

memory[memory_to_execute].operand2 ;

break;

case '-':

memory[memory_to_execute].result =

memory[memory_to_execute].operand1 -

memory[memory_to_execute].operand2 ;

break;

case '*':

memory[memory_to_execute].result =

memory[memory_to_execute].operand1 *

memory[memory_to_execute].operand2 ;

break;

case '/':

memory[memory_to_execute].result =

memory[memory_to_execute].operand1 /

memory[memory_to_execute].operand2 ;

break;

case '%':

memory[memory_to_execute].result =

memory[memory_to_execute].operand1 %

memory[memory_to_execute].operand2 ;

break;

} /* end of switch */

memory_to_execute = memory_to_execute + 1;

}

} /* end execute_memory */

void printer() /* print jobs */

{ else /* current_job != 0 */

{

P(my_semid, OK_TO_EXEC1);

if (load_job[current_job] == -1)

{

more_jobs = more_jobs -1;

P(my_semid, OK_TO_SET_OUTPUT1);

print_job[current_job] = -1;

V(my_semid, OK_TO_LOAD1);

V(my_semid, OK_TO_PRINT1);

}

else

{

execute_memory(current_job);

P(my_semid, OK_TO_SET_OUTPUT1);

pcbs[current_job + 2] = pcbs[1];

memory_to_output = pcbs[current_job + 2].start_loc;

where_to_output = pcbs[current_job + 2].output_loc;

for (i = 1; i

{

memory[where_to_output] = memory[memory_to_output];

memory_to_output = memory_to_output + 1;

where_to_output = where_to_output + 1;

}

load_job[current_job] = 0;

print_job[current_job] = 1;

V(my_semid, OK_TO_LOAD1);

V(my_semid, OK_TO_PRINT1);

} /* end for else for load job[1] != -1 */

}

current_job = (current_job + 1) % HOWMANY_JOBS;

} /* end while more jobs */

} /* end of cpu */

void execute_memory(int current_job)

{

int memory_to_print, current_print_job, more_print_jobs;

current_print_job = 0;

more_print_jobs = 2;

while (more_print_jobs)

{

if (current_print_job == 0)

{

P(my_semid, OK_TO_PRINT0);

if (print_job[current_print_job] == -1)

{

more_print_jobs = more_print_jobs - 1;

V(my_semid, OK_TO_SET_OUTPUT0);

}

else

{

memory_to_print = 20;

print_memory(current_print_job, memory_to_print);

print_job[current_print_job] = 0;

V(my_semid, OK_TO_SET_OUTPUT0);

}

} /* end for current_print_job == 0 */

else

{

P(my_semid, OK_TO_PRINT1);

if (print_job[current_print_job] == -1)

{

more_print_jobs = more_print_jobs - 1;

V(my_semid, OK_TO_SET_OUTPUT1);

}

else

{

memory_to_print = 30;

print_memory(current_print_job, memory_to_print);

print_job[current_print_job] = 0;

V(my_semid, OK_TO_SET_OUTPUT1);

}

} /* end of else for current_print_job */

current_print_job = (current_print_job + 1) % 2;

} /* end of while */

} /* end of printer */

void print_memory(int current_print_job, int memory_to_print)

{

int i;

printf("output for current job %d ", current_print_job);

for (i = 1; i

{

printf("%c %d %d %d ",

memory[memory_to_print].operation,

memory[memory_to_print].operand1,

memory[memory_to_print].operand2,

memory[memory_to_print].result );

memory_to_print = memory_to_print + 1;

}

printf(" ");

} /* end of print_memory */

~

3. Modify the loader.c" source code to satisfy the following two requirements: i. Use command-line arguments (i.e., main(int argc, char *argv[])) in the format: a.out N inputfile where a.out is the executable filename; N is the number of concurrent jobs, 1 sN S 10; inputfile is the filename of the input file. ii. Use the malloc() and free() functions to dynamically allocate the necessary semaphores and memory locations based on the number of concurrent computation jobs. For example, the following table shows some examples of the necessary semaphore numbers, memory size and location arrangement as the value of N changes. NNumber ofTotal Memory Semaphores Location Sizefor Loading Memory Location Arrangement 4 8 20 40 0-9 for job0 0-19 for Printing 10 19 for job0 20- 39 0-9 for job0 10 - 19 for job1 20 29 for job0 30 - 39 for job1 3 12 60 0- 29 30- 59 0-9 for job0 10 - 19 for job1 20- 29 for job2 30 - 39 for job0 40 - 49 for job1 50 -59 for job2

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Database Processing Fundamentals Design And Implementation

Authors: KROENKE DAVID M.

1st Edition

8120322258, 978-8120322257

Students also viewed these Databases questions

Question

What are the Five Phases of SDLC? Explain each briefly.

Answered: 1 week ago

Question

How can Change Control Procedures manage Project Creep?

Answered: 1 week ago