#define _XOPEN_SOURCE 600 // POSIX Standard X/Open6, incorporating POSIX 2004

#include <stdlib.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <unistd.h>

#include <sys/wait.h>

#include <string.h>

#include <mqueue.h>

#include <fcntl.h>

#include <sys/stat.h>

#define MAX_SIZE 100

#define KEY 512

struct process {

char name ;

int serviceTime ;

unsigned int priority ;

} ;

void fcfs ( mqd_t queueDescriptor ) ;

void roundRobin ( mqd_t queueDescriptor , int quantum ) ;

void priorityWithPreemption ( mqd_t queueDescriptor ) ;

void priorityWithoutPreemption ( mqd_t queueDescriptor ) ;

int main ( void ) {

struct process processInfo [ 5 ] ;

processInfo [ 0 ] . name = 'A' ;

processInfo [ 0 ] . serviceTime = 3 ;

processInfo [ 0 ] . priority = 1 ;

processInfo [ 1 ] . name = 'B' ;

processInfo [ 1 ] . serviceTime = 6 ;

processInfo [ 1 ] . priority = 1 ;

processInfo [ 2 ] . name = 'C' ;

processInfo [ 2 ] . serviceTime = 4 ;

processInfo [ 2 ] . priority = 2 ;

processInfo [ 3 ] . name = 'D' ;

processInfo [ 3 ] . serviceTime = 5 ;

processInfo [ 3 ] . priority = 2 ;

processInfo [ 4 ] . name = 'E' ;

processInfo [ 4 ] . serviceTime = 2 ;

processInfo [ 4 ] . priority = 3 ;

mqd_t queueDescriptor ;

// Message Queue Attribute

struct mq_attr attributes ;

attributes. mq_flags = 0 ; // or O_NONBLOCK

attributes. mq_maxmsg = 10 ; // # messages on queue

attributes. mq_msgsize = sizeof ( struct process ) ; // Max. message size (bytes)

attributes. mq_curmsgs = 0 ; // # of messages currently in queue

//Create Queue

if ( ( queueDescriptor = mq_open ( "/Task1MessageQueue" , O_CREAT | O_RDWR , 0660 , & attributes ) ) == - 1 ) {

perror ( "Before fork: mq_open()" ) ;

return EXIT_FAILURE ;

}

int child_pid ;

int choice = 0 ;

printf ( "



+++ Scheduling algorithms +++

" ) ;

printf ( "1 - FCFS

2 - Round Robin Quantum = 4

3 - Highest priority first with preemption

4 - Highest priority first without preemption

" ) ;

scanf ( "%d" , & choice ) ;

switch ( choice ) {

case 1 :

printf ( "

+++ FCFS +++

" ) ;

child_pid = fork ( ) ;

switch ( child_pid ) {

case - 1 :

perror ( "fork" ) ;

return EXIT_FAILURE ;

break ;

case 0 :

//Child Code

fcfs ( queueDescriptor ) ;

printf ( "Child: finished!

" ) ;

exit ( 0 ) ;

break ;

default :

//Parent Code

for ( int i = 0 ; i < 5 ; i ++ ) {

if ( mq_send ( queueDescriptor , ( const char * ) & processInfo [ i ] , sizeof ( struct process ) , 0 ) == - 1 ) {

perror ( "Parent: mq_send" ) ;

}

printf ( "Parent: Process %c goes into Message Queue

" , processInfo [ i ] . name ) ;

sleep ( 2 ) ;

}

if ( mq_close ( queueDescriptor ) == - 1 ) {

perror ( "Parent: mq_close" ) ;

}

wait ( 0 ) ;

break ;

}

break ;

case 2 :

printf ( "

+++ Round Robin Quantum = 4 +++

" ) ;

child_pid = fork ( ) ;

switch ( child_pid ) {

case - 1 :

perror ( "fork" ) ;

return EXIT_FAILURE ;

break ;

case 0 :

//Child Code

roundRobin ( queueDescriptor , 4 ) ;

printf ( "Child: finished!

" ) ;

exit ( 0 ) ;

break ;

default :

//Parent Code

for ( int i = 0 ; i < 5 ; i ++ ) {

if ( mq_send ( queueDescriptor , ( const char * ) & processInfo [ i ] , sizeof ( struct process ) , 0 ) == - 1 ) {

perror ( "Parent: mq_send" ) ;

}

printf ( "Parent: Process %c goes into Message Queue

" , processInfo [ i ] . name ) ;

sleep ( 2 ) ;

}

if ( mq_close ( queueDescriptor ) == - 1 ) {

perror ( "Parent: mq_close" ) ;

}

wait ( 0 ) ;

break ;

}

break ;

case 3 :

printf ( "

+++ Highest Priority First with preemeption +++

" ) ;

child_pid = fork ( ) ;

switch ( child_pid ) {

case - 1 :

perror ( "fork" ) ;

return EXIT_FAILURE ;

break ;

case 0 :

//Child Code

priorityWithPreemption ( queueDescriptor ) ;

printf ( "Child: finished!

" ) ;

exit ( 0 ) ;

break ;

default :

//Parent Code

for ( int i = 0 ; i < 5 ; i ++ ) {

if ( mq_send ( queueDescriptor , ( const char * ) & processInfo [ i ] , sizeof ( struct process ) , processInfo [ i ] . priority ) == - 1 ) {

perror ( "Parent: mq_send" ) ;

}

printf ( "Parent: Process %c goes into Message Queue

" , processInfo [ i ] . name ) ;

sleep ( 2 ) ;

}

if ( mq_close ( queueDescriptor ) == - 1 ) {

perror ( "Parent: mq_close" ) ;

}

wait ( 0 ) ;

break ;

}

break ;

case 4 :

printf ( "

+++ Highest Priority First without preemption +++

" ) ;

child_pid = fork ( ) ;

switch ( child_pid ) {

case - 1 :

perror ( "fork" ) ;

return EXIT_FAILURE ;

break ;

case 0 :

//Child Code

priorityWithoutPreemption ( queueDescriptor ) ;

printf ( "Child: finished!

" ) ;

exit ( 0 ) ;

break ;

default :

//Parent Code

for ( int i = 0 ; i < 5 ; i ++ ) {

if ( mq_send ( queueDescriptor , ( const char * ) & processInfo [ i ] , sizeof ( struct process ) , processInfo [ i ] . priority ) == - 1 ) {

perror ( "Parent: mq_send" ) ;

}

printf ( "Parent: Process %c goes into Message Queue

" , processInfo [ i ] . name ) ;

sleep ( 2 ) ;

}

if ( mq_close ( queueDescriptor ) == - 1 ) {

perror ( "Parent: mq_close" ) ;

}

wait ( 0 ) ;

break ;

}

break ;

}

//Remove Message Queue

if ( mq_unlink ( "/Task1MessageQueue" ) == - 1 ) {

perror ( "mq_unlink" ) ;

}

return EXIT_SUCCESS ;

}

void fcfs ( mqd_t queueDescriptor ) {

struct process arrivedProcess ;

if ( ( mq_receive ( queueDescriptor , ( char * ) & arrivedProcess , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child: mq_receive" ) ;

}

struct mq_attr attributes ;

while ( 1 ) {

printf ( "Child: Process %c has %d seconds remaining serviceTime

" , arrivedProcess. name , arrivedProcess. serviceTime ) ;

sleep ( 1 ) ;

arrivedProcess. serviceTime --;

if ( arrivedProcess. serviceTime == 0 ) {

//Check if still messages in queue

mq_getattr ( queueDescriptor , & attributes ) ;

if ( attributes. mq_curmsgs == 0 ) {

printf ( "Child: no new processes!

" ) ;

break ;

}

//Receive new message from queue

if ( ( mq_receive ( queueDescriptor , ( char * ) & arrivedProcess , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child in for loop: mq_receive" ) ;

}

}

}

}

void roundRobin ( mqd_t queueDescriptor , int quantum ) {

struct process arrivedProcess ;

if ( ( mq_receive ( queueDescriptor , ( char * ) & arrivedProcess , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child: mq_receive" ) ;

}

struct mq_attr attributes ;

int quantumCounter = 0 ;

while ( 1 ) {

printf ( "Child: Process %c has %d seconds remaining serviceTime

" , arrivedProcess. name , arrivedProcess. serviceTime ) ;

sleep ( 1 ) ;

arrivedProcess. serviceTime --;

quantumCounter ++;

if ( arrivedProcess. serviceTime == 0 ) {

//Check if still messages in queue

quantumCounter = 0 ;

mq_getattr ( queueDescriptor , & attributes ) ;

if ( attributes. mq_curmsgs == 0 ) {

printf ( "Child: no new processes!

" ) ;

break ;

}

//Receive new message from queue

if ( ( mq_receive ( queueDescriptor , ( char * ) & arrivedProcess , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child in for loop: mq_receive" ) ;

}

} else if ( quantumCounter == quantum ) {

printf ( "+++ Quantum = 4! +++

" ) ;

quantumCounter = 0 ;

//Check if still messages in queue

mq_getattr ( queueDescriptor , & attributes ) ;

if ( attributes. mq_curmsgs == 0 ) {

printf ( "Child: no new processes!

" ) ;

break ;

}

if ( mq_send ( queueDescriptor , ( const char * ) & arrivedProcess , sizeof ( struct process ) , 0 ) == - 1 ) {

perror ( "Child: mq_send" ) ;

}

printf ( "Child: Process %c goes into Message Queue AGAIN

" , arrivedProcess. name ) ;

//Receive new message from queue

if ( ( mq_receive ( queueDescriptor , ( char * ) & arrivedProcess , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child in for loop: mq_receive" ) ;

}

}

}

}

void priorityWithPreemption ( mqd_t queueDescriptor ) {

struct process arrivedProcess ;

struct process process2 ;

if ( ( mq_receive ( queueDescriptor , ( char * ) & arrivedProcess , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child: mq_receive" ) ;

}

struct mq_attr attributes ;

while ( 1 ) {

printf ( "Child: Process %c has %d seconds remaining serviceTime

" , arrivedProcess. name , arrivedProcess. serviceTime ) ;

sleep ( 1 ) ;

arrivedProcess. serviceTime --;

//Check if someone has higher priority

mq_getattr ( queueDescriptor , & attributes ) ;

if ( attributes. mq_curmsgs != 0 ) {

if ( ( mq_receive ( queueDescriptor , ( char * ) & process2 , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child in for loop: mq_receive" ) ;

}

if ( process2. priority > arrivedProcess. priority ) {

printf ( "+++ Process %c has priority %d, and is bigger than Process %c with priority %d +++

" , process2. name , process2. priority , arrivedProcess. name , arrivedProcess. priority ) ;

if ( mq_send ( queueDescriptor , ( const char * ) & arrivedProcess , sizeof ( struct process ) , arrivedProcess. priority ) == - 1 ) {

perror ( "Child: mq_send" ) ;

}

printf ( "arrivedProcess %c goes into message queue AGAIN

" , arrivedProcess. name ) ;

arrivedProcess = process2 ;

} else {

if ( mq_send ( queueDescriptor , ( const char * ) & process2 , sizeof ( struct process ) , process2. priority ) == - 1 ) {

perror ( "Child: mq_send" ) ;

}

printf ( "Process2 %c goes into message queue AGAIN

" , process2. name ) ;

}

}

//serviceTime of a process is 0

if ( arrivedProcess. serviceTime <= 0 ) {

//Check if still messages in queue

mq_getattr ( queueDescriptor , & attributes ) ;

if ( attributes. mq_curmsgs == 0 ) {

printf ( "Child: no new processes!

" ) ;

break ;

}

//Receive new message from queue

if ( ( mq_receive ( queueDescriptor , ( char * ) & arrivedProcess , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child in for loop: mq_receive" ) ;

}

}

}

}

void priorityWithoutPreemption ( mqd_t queueDescriptor ) {

struct process arrivedProcess ;

if ( ( mq_receive ( queueDescriptor , ( char * ) & arrivedProcess , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child: mq_receive" ) ;

}

struct mq_attr attributes ;

while ( 1 ) {

printf ( "Child: Process %c has %d seconds remaining serviceTime

" , arrivedProcess. name , arrivedProcess. serviceTime ) ;

sleep ( 1 ) ;

arrivedProcess. serviceTime --;

if ( arrivedProcess. serviceTime == 0 ) {

//Check if still messages in queue

mq_getattr ( queueDescriptor , & attributes ) ;

if ( attributes. mq_curmsgs == 0 ) {

printf ( "Child: no new processes!

" ) ;

break ;

}

//Receive new message from queue

if ( ( mq_receive ( queueDescriptor , ( char * ) & arrivedProcess , sizeof ( struct process ) , NULL ) ) == - 1 ) {

perror ( "Child in for loop: mq_receive" ) ;

}

}

}