Search code examples
javagantt-chartround-robin

Display Gantt chart Java CPU Scheduling


I have been trying to create a gantt chart with the output of my program but i can't seem to figure out how to do it. This is a round Robin CPU Scheduling program.

EDIT:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

public class Display
{

/**
 * Display CPU Scheduling results
 * 
 * @param simulation
 *            Display Process table and Processes Execution Sequence
 */
public static void simulation()
{
    ArrayList<Pair> pairs = new ArrayList<Pair>();
    // Before starting the simulation, print first the generated processes
    Iterator<Process> it = RoundRobin.processes.iterator();

    RoundRobin.ps.println("--------------+---------------+--------------");
    RoundRobin.ps.println("ROUND ROBIN SIMULATION RESULT");
    RoundRobin.ps.println("--------------+---------------+--------------");
    RoundRobin.ps.println("TIME QUANTUM: " + RoundRobin.timeQuantum);
    RoundRobin.ps.println("--------------+---------------+--------------");
    RoundRobin.ps.printf("%27s%n", "PROCESSES");
    RoundRobin.ps.println("--------------+---------------+--------------");
    RoundRobin.ps.println("Process Name  | Arrival Time | Burst Time   |");

    while (it.hasNext())
    {
        Process process = it.next();
        RoundRobin.ps.printf("%-14s%1s%-13d%1s%-13s%1s%n", process.getName(), "| ", process.getArrivalTime(), "| ",
                process.getBurstTime(), "|");
    }
    RoundRobin.ps.println("--------------+---------------+--------------");
    RoundRobin.ps.println();

    RoundRobin.ps.printf("%10s%n", "|===========================| GANTT CHART |===========================|");

    CPU cpu = new CPU();
    Queue<Process> waitingQueue = new LinkedList<Process>();

    while (true)
    {
        // check if there are processes that has arrived and add them to the
        // waiting queue
        LinkedList<Process> arrivedProcesses = RoundRobin.getArrivedProcessed(cpu.getTime());

        it = arrivedProcesses.iterator();

        while (it.hasNext())
            waitingQueue.add(it.next());

        // check if the CPU is busy
        if (!cpu.isProcessing())
        {
            // if the CPU is not busy then get one of the process in the
            // waiting queue to be processed
            if (!waitingQueue.isEmpty())
                cpu.acceptProcess(waitingQueue.poll());
            else
                // if the waiting queue is empty then that means that the
                // CPU is idle
                pairs.add(new Pair(cpu.getTime(), "IDLE"));
        }

        // continue the process of the CPU
        if (cpu.isProcessing())
        {
            cpu.doProcess();
            pairs.add(new Pair(cpu.getTime(), cpu.getProcess().getName()));

            // check if the CPU has Finished processing the previous
            // proccess, if so continue to the next process in queue.
            if (cpu.hasFinishedProcess())
            {
                RoundRobin.finishedProcesses.add(cpu.getProcess());

                cpu.clearProcess();

                if (!waitingQueue.isEmpty())
                    cpu.acceptProcess(waitingQueue.poll());
            } else
            {
                // context switching
                Process process = cpu.getProcess();

                if (process.getProcessedBurstTime() % RoundRobin.timeQuantum == 0)
                {
                    // context switch by removing the current process and
                    // sending it back to the end of the ready queue.
                    cpu.clearProcess();
                    // RoundRobin.ps.println("\n");
                    waitingQueue.add(process);

                    // if there is a process assign it to the waiting queue.
                    if (!waitingQueue.isEmpty())
                        cpu.acceptProcess(waitingQueue.poll());
                }
            }
        }

        // verify if all processes have finished processing.
        if (waitingQueue.isEmpty() && !cpu.isProcessing() && RoundRobin.processes.isEmpty())

            break;

        cpu.incrementTime();
        RoundRobin.increaseWaitingTimeToWaitingProcesses(waitingQueue);

    }

    // Displays Gantt chart
    Iterator<Pair> pairIt = pairs.iterator();
    String first = "";
    String second = "";

    while (pairIt.hasNext())
    {
        Pair current = pairIt.next();

        first += "| " + current.getProcessState() + " |";
        second += "  " + current.getTime() + "  ";

        if (pairIt.hasNext())
        {
            first += " ====== ";
            second += "        ";
        }
    }

    RoundRobin.ps.println(first);
    RoundRobin.ps.println(second);

    RoundRobin.ps.printf("%n%10s", "|===========================|============|===========================|");

    RoundRobin.ps.println();
    RoundRobin.ps.println();
    RoundRobin.ps.println("Average Waiting Time: \t\t" + RoundRobin.getAverageWaitingTime());
    RoundRobin.ps.println("Average Turn Around Time: \t" + RoundRobin.getAverateTurnAroundTime());
    RoundRobin.ps.printf("%-1s%.0f%1s%n", "Utilization Rate: \t\t", RoundRobin.getUtilizationRate(cpu), "%");
    RoundRobin.ps.printf("%-1s%.2f%1s%n", "Throughput: \t\t\t", RoundRobin.getThroughput(cpu),
            " processes per unit time");
    RoundRobin.ps.println();
    RoundRobin.ps.flush();
}
}
/**
* Saves process State in an ArrayList to output after simulation ends.
* 
* @param Pair
*            represents one pair (time and processState) and keep these pairs
*            in an ArrayList
*/
class Pair
{
private String  processState;
private int     time;

public Pair(int time, String processState)
{
    this.time = time;
    this.processState = processState;
}

public String getProcessState()
{
    return this.processState;
}

public int getTime()
{
    return this.time;
}
}
{
    return this.processState;
}

public int getTime()
{
    return this.time;
}

}

The code above outputs the following:

|===========================| GANTT CHART |===========================|

| P1 | ====== | P1 | ====== | P1 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P3 | ====== | P3 | ====== | P3 | ====== | P3 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P4 | ====== | P4 | ====== | P4 | ====== | P4 | ====== | P3 | ====== | P3 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P4 | ====== | P4 | ====== | P4 | ====== | P4 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P4 | ====== | P4 | ====== | P4 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P2 | ====== | P5 | ====== | P2 | ====== | P2 |
  0            1            2            3            4            5            6            7            8            9            10            11            12            13            14            15            16            17            18            19            20            21            22            23            24            25            26            27            28            29            30            31            32            33            34            35            36            37            38            39            40            41            42            43            44            45            46            47            48            49            50            51            52            53            54            55            56            57            58            59            60            61            62            63            64            65            66  

|===========================|============|===========================|

i can't dont want the repeated processes in the chart. Instead of showing 3 consecutive process P1 P1 P1 i just need one P1. With its CPU clock time Under it. Like the following.

|===================================================================================================| GANTT CHART |==========================================================================================================================================================|

| P1 | ====== | P2 | ====== | P3 | ====== | P2  | ====== | P4 | ====== | P3 | ====== | P2 | ====== | P5 | ====== | P4 | ====== | P2 | ====== | P5 | ====== | P4 | ====== | P2 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P5 | ====== | P5 | ====== |
0             3             7             11             15            19            21            25            29            33            37            41            44            48            52            56            60            64            65            66    

|===================================================================================================|============|===========================================================================================================================================================|

The Complete source code can be found here.


Solution

  • If it is not about displaying the results immediately i would suggest creating a small class that represents one pair (time and processState) and keep these pairs in an ArrayList while the simulation is running. At the end you can simply iterate through this list and create the two lines of your gantt chart.

    The small class could look like this:

    private class Pair {
        private String processState;
        private int time;
    
        public Pair(int time, String processState) {
            this.time = time;
            this.processState = processState;
        }
    
        public int getTime() {
            return this.time;
        }
    
        public String getProcessState() {
            return this.processState;
        }
    }
    

    And can be put into your 'Display' class as a private class. At the beginning of the 'simulate' method you would put:

    ArrayList<Pair> pairs = new ArrayList<Pair>();
    

    Now replace each 'logTime()' call with:

    pairs.add(new Pair(time, processState));
    

    When the computation is done you could do sth. like that:

    Iterator<Pair> pairIt = pairs.iterator();
    String first = "";
    String second = "";
    
    while(pairIt.hasNext()) {
        Pair current = pairIt.next();
    
        first += "| " + current.getProcessState() + " |";
        second += "  " + current.getTime() + "  ";
    
        if(pairIt.hasNext()) {
            first += " ====== ";
            second += "        ";
        }
    }
    
    RoundRobin.ps.printf(first);
    RoundRobin.ps.printf(second);
    

    Sure it does not account for different lengths of 'processState' or 'time' but it should give you an idea of how it works. You can then adjust the length of your header ('=====| Gantt Chart | ====') according to the length of 'first' or 'second'.