Option Explicit

Private Const TIME_SPLICE       As Integer = 3

Dim t           As Integer      ' Execution timer
Dim p           As Integer      ' Process counter
Dim index       As Integer      ' Index of current process
Dim curIndex    As Integer      ' Index of previously executed process
Dim onSPF       As Boolean

Private Sub cmdExecute_Click()
    
    Do While Not cpuScheduler.allComplete = True
        executeRR
        Sleep DELAY / 4
    Loop
    
    logEvent rtf, String(120, "-") & vbCrLf & "Done executing all the processes."
    lblAWT.Caption = cpuScheduler.getAverageWaitingTime
    lblATT.Caption = cpuScheduler.getAverageTurnAroundTime
    displayWaitingTime lvw
    
End Sub

Private Sub cmdQuit_Click()
    Unload Me
End Sub

Private Sub Form_Load()
    t = -1
    curIndex = -1
    onSPF = False
    InitList lvw
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set cpuScheduler = Nothing
End Sub

Private Sub executeRR()

    Dim remCPUBurst     As Integer

    ' Increment execution timer
    t = t + 1
    
    ' Fetch the process that has an arrival time equal to the current time value.
    index = getNextProcIDInReadyQueueByArrivalTime(t)
    
    If index > 0 And index <> curIndex Then
        ' A new process arrives at the ready queue.
        ' =========================================
        logEvent rtf, "Process " & cpuScheduler.getProcess(index).getProcessID & _
                 " arrives at the ready queue at time t = " & CStr(t) & _
                 " with a CPU burst of " & CStr(cpuScheduler.getProcess(index).getCPUBurst)
        
        cpuScheduler.getProcess(index).setTimeEnteredQueue = t
        
        If curIndex <> -1 Then
            ' There has been an executing process.
            If cpuScheduler.getProcess(curIndex).getExecutionTime = TIME_SPLICE Then
                
                logEvent rtf, "Process " & cpuScheduler.getProcess(index).getProcessID & _
                         " completed the time splice at time t = " & CStr(t)
                
                
                remCPUBurst = cpuScheduler.getProcess(curIndex).getCPUBurst - cpuScheduler.getProcess(curIndex).getExecutionTime
                                        
                ' Mark the current process as completed.
                cpuScheduler.getProcess(curIndex).setExecutionStatus = True
                
                ' Set the time the current process left the executing status.
                cpuScheduler.getProcess(curIndex).setTimeLeftQueue = t
                
                ' Set the time this process' partial CPU burst completed
                cpuScheduler.getProcess(curIndex).setTimeCompleted = t
                                        
                If remCPUBurst > 0 Then
                    
                    cpuScheduler.addProcess cpuScheduler.getProcess(curIndex).getProcessID, _
                                            cpuScheduler.getProcess(curIndex).getArrivalTime, _
                                            cpuScheduler.getProcess(curIndex).getCPUBurst - cpuScheduler.getProcess(curIndex).getExecutionTime, _
                                            t
                                            
                    logEvent rtf, "Process " & cpuScheduler.getProcess(index).getProcessID & _
                             " is being pushed back to the ready queue at time t = " & CStr(t) & _
                             " with a remaining CPU burst of " & CStr(remCPUBurst)
                                            
                                            
                Else
                
                    ' Process is complete.
                    logEvent rtf, "Process " & cpuScheduler.getProcess(curIndex).getProcessID & _
                             " executing at time t = " & CStr(t)
            
                    logEvent rtf, "Process " & cpuScheduler.getProcess(curIndex).getProcessID & _
                             " completed its CPU burst at time t = " & CStr(t)
                
                    ' The current process completes executing
                    ' Mark the current process as completed.
                    cpuScheduler.getProcess(curIndex).setExecutionStatus = True
                        
                    ' Set the time the current process left the executing status.
                    cpuScheduler.getProcess(curIndex).setTimeCompleted = t
                    
                    displayTurnAroundTime lvw, cpuScheduler.getProcess(curIndex).getProcessID, cpuScheduler.getProcess(curIndex)
                    
                    index = getNextProcIDInReadyQueueWithLowestCB(t)
                    
                    If index = -1 Then
                        Exit Sub
                    Else
                        cpuScheduler.getProcess(index).setTimeEnteredQueue = t
                        curIndex = index
                    End If
                
                End If
                
                
            Else
                                        
                ' Increment the process' execution time.
                cpuScheduler.getProcess(index).setExecutionTime = cpuScheduler.getProcess(index).getExecutionTime + 1
                                        
                logEvent rtf, "Process " & cpuScheduler.getProcess(index).getProcessID & _
                         " executing at time t = " & CStr(t)
                         
            End If
            
            curIndex = index
        
        Else
        
            logEvent rtf, "Process " & cpuScheduler.getProcess(index).getProcessID & _
                         " executing at time t = " & CStr(t)
            
            curIndex = index
            cpuScheduler.getProcess(curIndex).setExecutionTime = cpuScheduler.getProcess(curIndex).getExecutionTime + 1
                        
        End If
        
    Else
    
        If cpuScheduler.getProcess(curIndex).getExecutionTime = TIME_SPLICE Then
        
            
            logEvent rtf, "Process " & cpuScheduler.getProcess(curIndex).getProcessID & _
                             " executing at time t = " & CStr(t)
            
            logEvent rtf, "Process " & cpuScheduler.getProcess(curIndex).getProcessID & _
                         " completed its CPU burst at time t = " & CStr(t)
        
            ' The current process completes executing
            ' Mark the current process as completed.
            cpuScheduler.getProcess(curIndex).setExecutionStatus = True
                
            ' Set the time the current process left the executing status.
            cpuScheduler.getProcess(curIndex).setTimeCompleted = t
            
            displayTurnAroundTime lvw, cpuScheduler.getProcess(curIndex).getProcessID, cpuScheduler.getProcess(curIndex)
            
            index = getNextProcIDInReadyQueueWithLowestCB(t)
            
            If index = -1 Then
                Exit Sub
            Else
                cpuScheduler.getProcess(index).setTimeEnteredQueue = t
                curIndex = index
            End If
            
        Else
            ' The program execution flow comes here when the current executing process is not changed.
            logEvent rtf, "Process " & cpuScheduler.getProcess(curIndex).getProcessID & _
                             " executing at time t = " & CStr(t)
            
            cpuScheduler.getProcess(curIndex).setExecutionTime = cpuScheduler.getProcess(curIndex).getExecutionTime + 1
        End If
                
    End If
    DoEvents

End Sub



