#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>
//  you may need other standard header files




//  CITS2002 Project 1 2023
//  Student1:   STUDENT-NUMBER1   NAME-1
//  Student2:   STUDENT-NUMBER2   NAME-2




//  myscheduler (v1.0)
//  Compile with:  cc -std=c11 -Wall -Werror -o myscheduler myscheduler.c




//  THESE CONSTANTS DEFINE THE MAXIMUM SIZE OF sysconfig AND command DETAILS
//  THAT YOUR PROGRAM NEEDS TO SUPPORT.  YOU'LL REQUIRE THESE //  CONSTANTS
//  WHEN DEFINING THE MAXIMUM SIZES OF ANY REQUIRED DATA STRUCTURES.


#define MAX_DEVICES                     4
#define MAX_DEVICE_NAME                 20
#define MAX_COMMANDS                    10
#define MAX_COMMAND_NAME                20
#define MAX_SYSCALLS_PER_PROCESS        40
#define MAX_RUNNING_PROCESSES           50


//  NOTE THAT DEVICE DATA-TRANSFER-RATES ARE MEASURED IN BYTES/SECOND,
//  THAT ALL TIMES ARE MEASURED IN MICROSECONDS (usecs),
//  AND THAT THE TOTAL-PROCESS-COMPLETION-TIME WILL NOT EXCEED 2000 SECONDS
//  (SO YOU CAN SAFELY USE 'STANDARD' 32-BIT ints TO STORE TIMES).


#define DEFAULT_TIME_QUANTUM            100


#define TIME_CONTEXT_SWITCH             5
#define TIME_CORE_STATE_TRANSITIONS     10
#define TIME_ACQUIRE_BUS                20




//  ----------------------------------------------------------------------


#define CHAR_COMMENT                    '#'




//struct for each devices present
struct device
{
    /*contains name, readspeed, writespeed*/
    char name[MAX_DEVICE_NAME];//name of device
    int read_speed;
    int write_speed;
   
   
   
};


//struct for each syscalls made
 struct syscalls {
    //contains when its called, name, read, sleep and write values
    int when;//the time it takes for it to be in CPU
    char syscall_name[100];//name of actions sleep, read
    char device[100];//device required like hd or terminal
    char command[MAX_COMMAND_NAME];//command name
    int readvalue;
    int sleepvalue;
    int writevalue;




};


//struct for commands in the file
struct commands
{
    /*contains name and array of syscalls*/
    char command_name[MAX_COMMAND_NAME];//name for command
    struct syscalls calls[MAX_SYSCALLS_PER_PROCESS];//syscall struct arrays like read, write
    int states;//0 - READY, 1 - RUNNING, 2- BLOCKED
   
};










int timequantum = 0;
struct device type[MAX_DEVICES];//global struct for all devices
void read_sysconfig(char argv0[], char filename[])
{
    FILE *sysconfigs;
    char ch;
    int devicecounter = 0;//number of devices
    sysconfigs = fopen(filename,"r");
    if(NULL == sysconfigs){
        printf("file cannot be opened \n");//error message
    }
    char line[100];//line to print out column
    //int time = 0;//time quantum
    //char devices[MAX_DEVICES][MAX_DEVICE_NAME];
    //int readspeed;
    //int writespeed;
   
   
   
    int i = 0;
    while(fgets(line, sizeof(line), sysconfigs)){//put everything in the device struct
        char value[50];
        char read[50];
        char write[50];
        if(sscanf(line, "%*s %s", value) == 1){
            if(strstr(value, "devicename") == NULL){
                if(atoi(value)==0){
                    devicecounter++;
                    strcpy(type[i].name,value);
                    sscanf(line, "%*s %*s %s %s", read, write);
                    type[i].read_speed = atoi(read);
                    type[i].write_speed = atoi(write);
                    i++;
                }else{
                    timequantum = atoi(value);
                }
            }
        }
    }


   
   
    for(int i = 0; i < devicecounter; i++){
       
        //printf("%s %d %d\n", type[i].name, type[i].read_speed, type[i].write_speed);
       
       
    }
   


   
   
   
   
    }
    //return 0;


 
   
   


       
   


//a function to count the numebr of words in a row
int countWords(const char *line) {
    int wordCount = 0;
    bool inWord = false;


    // Iterate through each character in the line
    for (int i = 0; line[i] != '\0'; i++) {
        if (line[i] == ' ' || line[i] == '\t' || line[i] == '\n') {
            // If a whitespace character is encountered, it means we are not in a word
            inWord = false;
        } else if (!inWord) {
            // If a non-whitespace character is encountered and we were not in a word, it's the start of a new word
            inWord = true;
            wordCount++;
        }
    }


    return wordCount;
}


int counts = 0;
struct commands process[MAX_COMMANDS];//struct for commands
void read_commands(char argv0[], char filename[])
{
    FILE *commands;
    commands = fopen(filename,"r");
     if(NULL == commands){
        printf("file cannot be opened \n");//error message
    }
    int column = 0;//column index for device name
    char line[100];//line to print out column
    //int counts = 0;//number of commands
    int i =0;
    int j =0;
    while (fgets(line, sizeof(line), commands)) {
       int words=countWords(line);
        if(words == 1){
            char value[100];
            if(sscanf(line, "%s", value) == 1){
                if((strstr(value,"#") == NULL) && (atoi(value)==0)){
                strcpy(process[i].command_name,value);
                //printf("%s\n",process[i].command_name);
                counts++;
               
                j = 0;//reset count for new struct
                }
            }
        }
        if(words == 2){//if 2, it is either wait or exit
            char value1[50];
            char name[50];
            if(sscanf(line,"%s %s", value1, name)==2){
                process[i].calls[j].when = atoi(value1);
                strcpy(process[i].calls[j].syscall_name, name);
                j++;
                if(strstr(name,"exit")!=NULL){
                    i++;//if exit move on to next struct
                }
            }
        }
        if(words ==3){//if 3, it is either sleeping or spawning
            char value1[50];
            char name[50];
            char value2[50];
            if(sscanf(line, "%s %s %s", value1, name, value2)==3){
                process[i].calls[j].when = atoi(value1);
                strcpy(process[i].calls[j].syscall_name,name);
                if(atoi(value2) == 0){
                    strcpy(process[i].calls[j].command,value2);
                }else{
                    process[i].calls[j].sleepvalue = atoi(value2);
                }
                j++;
            }
        }
        if(words ==4){//if there are 4 words its either reading or writing
            char value1[50];
            char name[50];
            char devices[50];
            char value2[50];
            if(sscanf(line, "%s %s %s %s", value1, name, devices, value2)==4){
                process[i].calls[j].when = atoi(value1);
                strcpy(process[i].calls[j].syscall_name,name);
                strcpy(process[i].calls[j].device,devices);
                if(strstr(name,"write")!=NULL){
                    process[i].calls[j].writevalue = atoi(value2);
                }
                if(strstr(name,"read")!=NULL){
                    process[i].calls[j].readvalue = atoi(value2);
                }
                j++;
            }
        }
       




   


}}


   
int total_time = 0;
int cpu_time = 0;



//  ----------------------------------------------------------------------
void execute_commands(void) {
    
    int i = 0;
    int j = 0;

    while (i < counts) {
        // Initialize the initial state transition
        if (process[i].calls[j - 1].when < 0) {
            process[i].calls[j - 1].when = 0;
        }

        // Handle the READY state
        if (process[i].states == 0) {
            process[i].states = 1;
            total_time += TIME_CONTEXT_SWITCH;

            // Transition to RUNNING
            total_time += TIME_CORE_STATE_TRANSITIONS;

            // Increment CPU time
            cpu_time++;

            // Check if the process should sleep
            if (strstr(process[i].calls[j].syscall_name, "sleep")) {
                process[i].states = 2;
                total_time += process[i].calls[j].sleepvalue + TIME_CORE_STATE_TRANSITIONS;
            }
        }

        // Handle the RUNNING state
        if (process[i].states == 1) {
            int remaining_time = process[i].calls[j].when - process[i].calls[j - 1].when;

            if (remaining_time >= timequantum) {
                // The process's time quantum has expired
                total_time += timequantum;

                // Transition to READY
                total_time += TIME_CORE_STATE_TRANSITIONS;
                cpu_time += timequantum;

                // Increment the syscall index
                j++;

                // Check if the process should sleep
                if (strstr(process[i].calls[j].syscall_name, "sleep")) {
                    process[i].states = 2;
                    total_time += process[i].calls[j].sleepvalue + TIME_CORE_STATE_TRANSITIONS;
                }
            } else {
                // The process is still running within its time quantum
                total_time += remaining_time;
                cpu_time += remaining_time;

                // Transition to READY
                total_time += TIME_CORE_STATE_TRANSITIONS;

                // Increment the syscall index
                j++;

                // Check if the process should sleep
                if (strstr(process[i].calls[j].syscall_name, "sleep")) {
                    process[i].states = 2;
                    total_time += process[i].calls[j].sleepvalue + TIME_CORE_STATE_TRANSITIONS;
                }
            }
        }

        // Handle the SLEEPING state
        if (process[i].states == 2) {
            total_time += process[i].calls[j].sleepvalue + TIME_CORE_STATE_TRANSITIONS;

            // Transition to READY
            total_time += TIME_CORE_STATE_TRANSITIONS;

            // Increment the syscall index
            j++;
        }

        // Check if the process should exit
        if (strstr(process[i].calls[j].syscall_name, "exit")) {
            total_time += TIME_CORE_STATE_TRANSITIONS;

            // Increment the syscall index
            j++;

            // Move to the next process if available
            i++;

            // Transition to RUNNING if there's a next process
            if (i < counts) {
                process[i].states = 1;
                total_time += TIME_CONTEXT_SWITCH;
                total_time += TIME_CORE_STATE_TRANSITIONS;
                cpu_time++;

                // Check if the next process should sleep
                if (strstr(process[i].calls[j].syscall_name, "sleep")) {
                    process[i].states = 2;
                    total_time += process[i].calls[j].sleepvalue + TIME_CORE_STATE_TRANSITIONS;
                }
            }
        }
    }

    printf("measurements %d %d\n", total_time, cpu_time);
}



int main(int argc, char *argv[])
{
   
//  ENSURE THAT WE HAVE THE CORRECT NUMBER OF COMMAND-LINE ARGUMENTS
    if(argc != 3) {
        printf("Usage: %s sysconfig-file command-file\n", argv[0]);
        exit(EXIT_FAILURE);
    }








//  READ THE SYSTEM CONFIGURATION FILE
    read_sysconfig(argv[0], argv[1]);


   


//  READ THE COMMAND FILE
    read_commands(argv[0], argv[2]);


//  EXECUTE COMMANDS, STARTING AT FIRST IN command-file, UNTIL NONE REMAIN
    execute_commands();


   


//  PRINT THE PROGRAM'S RESULTS
    printf("measurements  %i  %d\n", total_time, cpu_time);
   
    //printf("%d\n",total_time);
    printf("%d\n",process[0].calls[0].when);
   
   


   


    exit(EXIT_SUCCESS);
}


//  vim: ts=8 sw=4 

C Language online compiler

Write, Run & Share C Language code online using OneCompiler's C online compiler for free. It's one of the robust, feature-rich online compilers for C language, running the latest C version which is C18. Getting started with the OneCompiler's C editor is really simple and pretty fast. The editor shows sample boilerplate code when you choose language as 'C' and start coding!

Read inputs from stdin

OneCompiler's C online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample C program which takes name as input and print your name with hello.

#include <stdio.h>
int main()
{
    char name[50];
    printf("Enter name:");
    scanf("%s", name);
    printf("Hello %s \n" , name );
    return 0;
    
}

About C

C language is one of the most popular general-purpose programming language developed by Dennis Ritchie at Bell laboratories for UNIX operating system. The initial release of C Language was in the year 1972. Most of the desktop operating systems are written in C Language.

Key features:

  • Structured Programming
  • Popular system programming language
  • UNIX, MySQL and Oracle are completely written in C.
  • Supports variety of platforms
  • Efficient and also handle low-level activities.
  • As fast as assembly language and hence used as system development language.

Syntax help

Loops

1. If-Else:

When ever you want to perform a set of operations based on a condition if-else is used.

if(conditional-expression) {
   // code
} else {
   // code
}

You can also use if-else for nested Ifs and if-else-if ladder when multiple conditions are to be performed on a single variable.

2. Switch:

Switch is an alternative to if-else-if ladder.

switch(conditional-expression) {    
case value1:    
 // code    
 break;  // optional  
case value2:    
 // code    
 break;  // optional  
...    
    
default:     
 // code to be executed when all the above cases are not matched;    
} 

3. For:

For loop is used to iterate a set of statements based on a condition.

for(Initialization; Condition; Increment/decrement){  
  // code  
} 

4. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(condition) {  
 // code 
}  

5. Do-While:

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

do {
  // code 
} while (condition); 

Arrays

Array is a collection of similar data which is stored in continuous memory addresses. Array values can be fetched using index. Index starts from 0 to size-1.

Syntax

One dimentional Array:

data-type array-name[size];

Two dimensional array:

data-type array-name[size][size];

Functions

Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity.

Two types of functions are present in C

  1. Library Functions:

Library functions are the in-built functions which are declared in header files like printf(),scanf(),puts(),gets() etc.,

  1. User defined functions:

User defined functions are the ones which are written by the programmer based on the requirement.

How to declare a Function

return_type function_name(parameters);

How to call a Function

function_name (parameters)

How to define a Function

return_type function_name(parameters) {  
  //code
}