/** makeing progress: increase one step for each running process in the cpus * increase one step for each i/o burst in device_queue * increase one waiting time for each process in ready_queue * */ void nextUnitTime(void) { int i; int ioSize = device_queue.size; /* increase step for processes in device queue */ for(i = 0; i < ioSize; i++) { process *dequeuedProcess = device_queue.front->data; dequeueProcess(&device_queue); (dequeuedProcess->bursts[dequeuedProcess->currentBurst].step)++; enqueueProcess(&device_queue, dequeuedProcess); } /* increase waiting time for processes in ready_queue */ for(i = 0; i < ready_queue.size; i++) { process *dequeuedProcess = ready_queue.front->data; dequeueProcess(&ready_queue); dequeuedProcess->waitingTime++; enqueueProcess(&ready_queue, dequeuedProcess); } /* increase step in running cpus */ for(i = 0; i < NUMBER_OF_PROCESSORS; i++) { if(cpus[i] != NULL) { ((cpus[i]->bursts[cpus[i]->currentBurst]).step)++; /* decrease the cpu running time by 1 */ cpus[i]->quantumRemaining--; } } }
// Updates the dispatcher // @par: PCB pointer process PCB // @ret: none void enqueueToPriority(PCB *process) { int p = process->priority; if (p == 0) { if (!realTimeQueue) { realTimeQueue = initializeQueue(); } enqueueProcess(realTimeQueue, process); } else if (p == 1) { if (!p1Queue) { p1Queue = initializeQueue(); } enqueueProcess(p1Queue, process); } else if (p == 2) { if (!p2Queue) { p2Queue = initializeQueue(); } enqueueProcess(p2Queue, process); } else { if (!p3Queue) { p3Queue = initializeQueue(); } enqueueProcess(p3Queue, process); } }
void Verhogen(pcb_t *attuale){ int chiave = attuale->p_s.reg_a1; pcb_t *nonbloc; if(!(chiave < 0 || chiave >= USER_SEM) && (nonbloc = V(chiave))){ enqueueProcess(nonbloc); decSoftCounter(); } enqueueProcess(attuale); }
/* move any running processes that have finished their CPU burst to waiting, and terminate those that have finished their last CPU burst. */ void moveRunningProcesses(void) { int i; for (i=0;i<NUMBER_OF_PROCESSORS;i++) { if (cpus[i] != NULL) { /* if process' current (CPU) burst is finished */ if (cpus[i]->bursts[cpus[i]->currentBurst].step == cpus[i]->bursts[cpus[i]->currentBurst].length) { /* start process' next (I/O) burst */ cpus[i]->currentBurst++; /* move process to waiting queue if it is not finished */ if (cpus[i]->currentBurst < cpus[i]->numberOfBursts) { enqueueProcess(&waitingQueue, cpus[i]); /* otherwise, terminate it (don't put it back in the queue) */ } else { cpus[i]->endTime = simulationTime; } /* stop executing the process -since this will remove the process from the cpu immediately, but the process is supposed to stop running at the END of the current time step, we need to add 1 to the runtime */ cpus[i] = NULL; } } } }
/** based on nextUnitProcess, we have the process(es) that are ready to be added to ready_queue * and for processes in the ready_queue, we find any available cpus to allocate the processes. * Note: we need to sort the array by process id if they have the same scheduling criterion. */ void readyQtoCPU(void) { int i; /* reorder the temp array based on their pid, only happen when two arrival time is the same */ qsort(tempArray, tempArrayIndex, sizeof(process *), compareByPid); /* enqueue the elements in the temp to ready_queue */ for(i = 0; i < tempArrayIndex; i++) { enqueueProcess(&ready_queue, tempArray[i]); } /** reset tempArrayIndex to the front of array * since we need to restore process into it later on add io to ready_queue */ tempArrayIndex = 0; /* find some cpus to allocate them from ready_queue */ for(i = 0; i < NUMBER_OF_PROCESSORS; i++) { if(cpus[i] == NULL) { /* allocate process from ready_queue to cpu(if applicable) */ if(ready_queue.size == 0) { cpus[i] = NULL; } else { cpus[i] = ready_queue.front->data; dequeueProcess(&ready_queue); } } } }
/** from i/o to ready_queue. * Since we have device queue that hold numbers of processes with i/o bursting. * Now we want to detect any finished i/o burst process and enqueue it to tempArray again, * since the device_queue is not ordered to dequeue, So before we add it back to ready_queue, * we need to sort the tempArray again and add it back to ready_queue */ void ioToReadyQ(void) { int i; int ioSize = device_queue.size; for(i = 0; i < ioSize; i++) { /* the out element of the queue */ process *dequeuedProcess = (device_queue.front)->data; dequeueProcess(&device_queue); /** if i/o finish add it to tempArray, otherwise enqueue back to device_queue again and * try next element in device queue */ if(isBurstFinished(dequeuedProcess)) { /* move forward for burst */ (dequeuedProcess->currentBurst)++; /* since the i/o burst is finised, hence, we need to reset the timeSlice for next cpu burst */ dequeuedProcess->quantumRemaining = timeSlice; /* use temp array to temporarily store the dequeued processes */ tempArray[tempArrayIndex] = dequeuedProcess; tempArrayIndex++; } /* enqueue it back to device_queue and try next one */ else { enqueueProcess(&device_queue, dequeuedProcess); } } }
/* update processes in the waiting queue */ void waiting_to_ready() { int i = 0; int waiting_size = waitingQueue.size; for (i = 0; i < waiting_size; i++) { process *ready = waitingQueue.front->data; dequeueProcess(&waitingQueue); if (ready->bursts[ready->currentBurst].step == ready->bursts[ready->currentBurst].length) { ready->currentBurst++; if (ready->bursts[ready->currentBurst].length < time_slice) { //defaults to fcfs ready->quantumRemaining = INT32_MAX; } else if (ready->bursts[ready->currentBurst].length < time_slice_1) { //defaults to fcfs ready->quantumRemaining = INT32_MAX; } if (ready->currentQueue == 0) { ready->quantumRemaining = time_slice; //context_switches++; } else if (ready->currentQueue == 1) { ready->quantumRemaining = time_slice_1; //context_switches++; } else { ready->quantumRemaining = INT32_MAX; context_switches++; // processes time didnt not expire so context switches comes from I/O(waiting queue) instead } tmp_ready_process[tmp_ready_process_size++] = ready; } else { enqueueProcess(&waitingQueue, ready); } } }
// does the heavy work. // initially checks if puIndex is equal to the bursts currently occuring, and if so, switches to an I/o bust // the cpu is then enqued into the waiting queure // if there are bursts beyond the time for the process, the cpu is sent back into the waiting queue // otherwise it is nulled. void cpuBurstAllocation(int cpuIndex, int cpuUse) { while (cpuIndex < NUMBER_OF_PROCESSORS) { if (cpus[cpuIndex] != NULL) { // check if cpu occupied with process if (cpus[cpuIndex]->bursts[cpus[cpuIndex]->currentBurst].length == cpus[cpuIndex]->bursts[cpus[cpuIndex]->currentBurst].step) { cpus[cpuIndex]->currentBurst++; // switch to I/O burst if (cpus[cpuIndex]->currentBurst < cpus[cpuIndex]->numberOfBursts) { enqueueProcess(&waitingQueue, cpus[cpuIndex]); } else { // add to waiting queue bursts remaining or otherwise terminate from cpu cpus[cpuIndex]->endTime = timer; } cpus[cpuIndex] = NULL; } else { // this takes and looks for remaining processes. basically if not actuallly occupied by current process, it will store it wither in temporary array or remove time for each cpu step. if (cpus[cpuIndex]->quantumRemaining == 0) { // store processes with expired time slices in temporary array for now which will be referenced in waiting queue check tempProcess[tempProcessSize] = cpus[cpuIndex]; tempProcessSize++; cpus[cpuIndex] = NULL; context++; } else { cpus[cpuIndex]->bursts[cpus[cpuIndex]->currentBurst].step++; cpus[cpuIndex]->quantumRemaining--; //decrease remaining time slice cpuUse++; cpuUseTotal++; } } } cpuIndex++; } }
/* move any waiting processes that are finished their I/O bursts to ready */ void moveWaitingProcesses(void) { int i; int size = waitingQueue.size; /* place processes finished their I/O bursts into an intermediate array so that they will be sorted by priority and added to the ready queue */ for (i=0;i<size;i++) { process *front = waitingQueue.front->data; /* get process at front */ dequeueProcess(&waitingQueue); /* dequeue it */ assert(front->bursts[front->currentBurst].step <= front->bursts[front->currentBurst].length); /* if process' current (I/O) burst is finished, move it to the ready queue, else return it to the waiting queue */ if (front->bursts[front->currentBurst].step == front->bursts[front->currentBurst].length) { /* switch to next (CPU) burst and place in ready queue */ front->currentBurst++; preReadyQueue[preReadyQueueSize++] = front; } else { enqueueProcess(&waitingQueue, front); } } }
void Passeren (pcb_t *attuale){ /*la chiave del processo che ha chiamato una P*/ int chiave = attuale -> p_s.reg_a1; if((chiave < 0 || chiave >= USER_SEM ) || P(chiave, attuale)){ enqueueProcess(attuale); } }
// updates the queue to coincide with FIFO structure of RR // if it is at front of the queue, dequeue that, and then enqueue the next process at the front void updateQueues() { //check front of queue process *front = readyQueue.front->data; dequeueProcess(&readyQueue); front->waitingTime++; // increment waiting time of each process in waiting queue enqueueProcess(&readyQueue, front); }
/* increment waiting time for each process in the ready queue */ void updateReadyProcesses(void) { int i; for (i=0;i<readyQueue.size;i++) { process *front = readyQueue.front->data; /* get process at front */ dequeueProcess(&readyQueue); /* dequeue it */ front->waitingTime++; /* increment waiting time */ enqueueProcess(&readyQueue, front); /* enqueue it again */ } }
/* updates the waiting time of the CPU */ void refresh_processes() { int j; // update CPU BOUND waiting process for (j = 0; j < readyQueue.size; j++) { process *CPU_BOUND = readyQueue.front->data; dequeueProcess(&readyQueue); CPU_BOUND->waitingTime++; enqueueProcess(&readyQueue, CPU_BOUND); } }
/** from cpu to i/o * For cpu burst to I/O burst, loop over all cpus, if any one is allocated to a process * then we need to check if current cpu burst has been finished (step = length), if so, * we need to check if it is not the last cpu burst, enqueue it to waiting queue, otherwise * set the current clockTime to the process end time. Last, free the corresponding CPU. */ void cpuOut(void) { int i; int tempIndex = 0; process *temp[NUMBER_OF_PROCESSORS]; for(i = 0; i < NUMBER_OF_PROCESSORS; i++) { // Note that initiallly there is no cpu running on any processes. if(cpus[i] != NULL) { /* check if current burst is finished */ if(isBurstFinished(cpus[i])) { (cpus[i]->currentBurst)++; /* do another check for endtime or just a enqueue step */ if((cpus[i])->currentBurst < (cpus[i])->numberOfBursts) { enqueueProcess(&device_queue, cpus[i]); } else { cpus[i]->endTime = clockTime; } /* free current working cpu */ cpus[i] = NULL; } // If the current cpu burst is not finised but the time is over. else if(cpus[i]->quantumRemaining == 0) { /* for processes running in the cpus, if time is over but the cpu burst is not finished, * that's where context switches happen, at this point, process(es) should go to ready_queue * instead of going to i/o queue, and wait to be assigned next available cpu. */ temp[tempIndex] = cpus[i]; temp[tempIndex]->quantumRemaining = timeSlice; tempIndex++; totalCW++; cpus[i] = NULL; } } } /* like tempArray in i/o to ready_queue function call, there might be several processes that need * to be added to the tail of ready_queue, so we need to sort them by the process id. */ qsort(temp, tempIndex, sizeof(process *), compareByPid); for(i=0; i < tempIndex; i++) { enqueueProcess(&ready_queue, temp[i]); } }
void increase_io_work() { int j; int size = waitingQueue.size; // update waiting state I\O burst for (j = 0; j < size; j++) { process *I_O = waitingQueue.front->data; dequeueProcess(&waitingQueue); I_O->bursts[I_O->currentBurst].step++; enqueueProcess(&waitingQueue, I_O); } }
/* increment each waiting process' current I/O burst's progress */ void updateWaitingProcesses(void) { int i; int size = waitingQueue.size; for (i=0;i<size;i++) { process *front = waitingQueue.front->data; /* get process at front */ dequeueProcess(&waitingQueue); /* dequeue it */ /* increment the current (I/O) burst's step (progress) */ front->bursts[front->currentBurst].step++; enqueueProcess(&waitingQueue, front); /* enqueue it again */ } }
/** * * Gets the most ready process and puts it the Cpu for execution */ void most_ready_running_in_cpu() { int i = 0; qsort(tmp_ready_process, tmp_ready_process_size, sizeof (process*), compareProcessIds); for (i = 0; i < tmp_ready_process_size; i++) { enqueueProcess(&readyQueue, tmp_ready_process[i]); } // at this point we feed the pre ready process into the CPU tmp_ready_process_size = 0; for (i = 0; i < NUMBER_OF_PROCESSORS; i++) { if (CPU[i] == NULL) { CPU[i] = get_next_sch_process(); } } }
void refresh_processes() { int j; int size = waitingQueue.size; // update waiting state I\O burst for (j = 0; j < size; j++) { process *I_O = waitingQueue.front->data; dequeueProcess(&waitingQueue); I_O->bursts[I_O->currentBurst].step++; enqueueProcess(&waitingQueue, I_O); } // update CPU BOUND process for (j = 0; j < readyQueue.size; j++) { process *CPU_BOUND = readyQueue.front->data; dequeueProcess(&readyQueue); CPU_BOUND->waitingTime++; enqueueProcess(&readyQueue, CPU_BOUND); } // increases work done by either I/O or CPU bound processes for (j = 0; j < NUMBER_OF_PROCESSORS; j++) { if (CPU[j] != NULL) { CPU[j]->bursts[CPU[j]->currentBurst].step++; } } }
void Create_Brother(pcb_t *attuale){ pcb_t *fratello; state_t *stato_fratello; fratello = get_Pcb(); stato_fratello = (state_t *) attuale ->p_s.reg_a1; if(stato_fratello || fratello){ //fratello->priority=p_s.reg_a2; insertChild(attuale, fratello); attuale->p_s.reg_v0 =0; enqueueProcess(attuale); } else { attuale -> p_s.reg_v0 = -1; return; } }
void waiting_to_ready() { int i = 0; ; int waitingQueueSize = waitingQueue.size; for (i = 0; i < waitingQueueSize; i++) { process *ready = waitingQueue.front->data; dequeueProcess(&waitingQueue); if (ready->bursts[ready->currentBurst].step == ready->bursts[ready->currentBurst].length) { ready->currentBurst++; tmp_ready_process[tmp_ready_process_size++] = ready; } else { enqueueProcess(&waitingQueue, ready); } } }
// go through the qwaiting queue and deqeue that front FIFO burst // complete it's value // and then enqueue it eitehr back into the qaiting queue if it is not finished, or into the preReadyQueue to be placed in the ready queue void dequeueEnqueueWaitingBusts(int waitingIndex, int waitingQueueSize) { //check the front of queue process *front = waitingQueue.front->data; if (front->bursts[front->currentBurst].length == front->bursts[front->currentBurst].step) { // switch to cpu burst that is current at front front->currentBurst++; dequeueProcess(&waitingQueue); preReadyQueue[preReadyQueueSize++] = front; } else { //I/O burst not finished front->bursts[front->currentBurst].step++; dequeueProcess(&waitingQueue); enqueueProcess(&waitingQueue, front); } }
void Create_Process (pcb_t *attuale){ pcb_t *figlio = get_Pcb(); /*registro a1 e l'indirizzo fisico dello state_t del nuovo processo*/ state_t *stato_figlio = (state_t *) attuale -> p_s.reg_a1; if ((stato_figlio) || (figlio)){ /*se il processo figlio viene creato corretamente, settiamo tutti i suoi campi*/ /*non impplementiamo la priorita'*/ /*figlio->priority=p_s.reg_a2;*/ insertChild(attuale, figlio); attuale -> p_s.reg_v0 = 0; enqueueProcess(attuale); } else { /*se il processo figlio non viene chiamato*/ attuale -> p_s.reg_v0 = -1; return; } }
/* move ready processes into free cpus according to scheduling algorithm */ void moveReadyProcesses(void) { int i; /* sort processes in the intermediate preReadyQueue array by priority, and add them to the ready queue prior to moving ready procs. into CPUs */ qsort(preReadyQueue, preReadyQueueSize, sizeof(process*), compareProcessPointers); for (i=0;i<preReadyQueueSize;i++) { enqueueProcess(&readyQueue, preReadyQueue[i]); } preReadyQueueSize = 0; /* for each idle cpu, load and begin executing the next scheduled process from the ready queue. */ for (i=0;i<NUMBER_OF_PROCESSORS;i++) { if (cpus[i] == NULL) { cpus[i] = nextScheduledProcess(); } } }
/** * Move finish process into the waiting queue and terminate finish CPU or I/O bursts */ void running_process_to_waiting() { int i; for (i = 0; i < NUMBER_OF_PROCESSORS; i++) { if (CPU[i] != NULL) { fprintf(log_file, "CPU BURST && I/O BURST:%d\t", CPU[i]->bursts[CPU[i]->currentBurst].length); fprintf(log_file, "STEPS:%d\n", CPU[i]->bursts[CPU[i]->currentBurst].step); if (CPU[i]->bursts[CPU[i]->currentBurst].step == CPU[i]->bursts[CPU[i]->currentBurst].length) { //context_switches++; CPU[i]->currentBurst++; if (CPU[i]->currentBurst < CPU[i]->numberOfBursts) { enqueueProcess(&waitingQueue, CPU[i]); // Puts the finish Burst into the waiting queue fprintf(log_file, "Waiting process id:%d\t&& Current Process id:%d\n", waitingQueue.front->data->pid, CPU[i]->pid); } else { CPU[i]->endTime = simulation_time; last_process_end_time = simulation_time; } CPU[i] = NULL; } } } }
// Updates the dispatcher // @par: int current time (quantum) // @ret: int 1 for process put into real time queue // @ret: int 0 otherwise int updateDispatcher(int time) { // Create a pointer to the dispatcher so we don't modify dispatcher directly unless we need to Queue *queuePtr = dispatcher; // Create a new queue for elements that weren't able to be added Queue *newDispatcher = initializeQueue(); int rtQUpdated = 0; // Checks if dispatcher is empty if (!(queuePtr)) { printf("The queue is empty!\n\n"); return 0; } // Iterate through each element in the queue int i = 0; int count = numElems(queuePtr); // If the first process is NULL, we don't want to iterate through them // Double check that there are elements in queue if (queuePtr->process == NULL) { i = count; } // Keep an indicator to see if anything breaks int broken = 0; // Iterate through each element in the dispatcher while (i < count) { // Dequeue the next process from the queue PCB *currentProcess = dequeueProcess(&queuePtr)->process; // Queue is empty // Triple check if (currentProcess == NULL) { printf("BROKEN!\n"); broken = 1; break; } // If the process has "arrived", attempt to allocate resources to it if (time >= currentProcess->arrivalTime) { // Attempt to allocate resources to the process. int allocResult = allocateResources(currentProcess); if (allocResult) { // Resources were allocated successfully printf("* INITIALIZED pid: %d", currentProcess->pid); if (currentProcess->priority == 0) { rtQUpdated = 1; printf(", a real time process"); } printf("\n\n"); // Send the process to join the appropriate priority queue enqueueToPriority(currentProcess); } else { // Resources could not be allocated, move the process back on the dispatcher queue enqueueProcess(newDispatcher, currentProcess); } } else { // The time has not come for this process, add it to the new dispatcher enqueueProcess(newDispatcher, currentProcess); } i++; } // If the queue wasn't broken if (!broken) { if (dispatcher == NULL) { cleanQueue(dispatcher); } dispatcher = newDispatcher; } return rtQUpdated; }
/** * Move finish process into the waiting queue and terminate finish CPU or I/O bursts */ void running_process_to_waiting() { int i, j, k, l, m, x; j = 0; k = 0; l = 0; m = 0; int rem_time = 0; for (i = 0; i < NUMBER_OF_PROCESSORS; i++) { if (CPU[i] != NULL) { fprintf(log_file, "STEPS:%d\n", CPU[i]->bursts[CPU[i]->currentBurst].step); // at some point step will be equal to length if (CPU[i]->bursts[CPU[i]->currentBurst].step == CPU[i]->bursts[CPU[i]->currentBurst].length) { fprintf(log_file, "DONE PROCESS ID:%d\t && RT\t:%d\n", CPU[i]->pid, rem_time); CPU[i]->currentBurst++; if (CPU[i]->currentBurst < CPU[i]->numberOfBursts) { enqueueProcess(&waitingQueue, CPU[i]); // Puts the finish Burst into the waiting queue fprintf(log_file, "Waiting process id:%d\t&& Current Process id:%d\n", waitingQueue.front->data->pid, CPU[i]->pid); } else { CPU[i]->endTime = simulation_time; last_process_end_time = CPU[i]->endTime; } CPU[i] = NULL; //first level } else if (CPU[i]->quantumRemaining == 0 && CPU[i]->currentQueue == 0) { // process that doesn't end with the //given time slices fprintf(log_file, "first time slice is met\n"); fprintf(log_file, "PID:%d\tLength:%d\n", CPU[i]->pid, CPU[i]->bursts[CPU[i]->currentBurst].length); // give that process the second time slice CPU[i]->quantumRemaining = time_slice_1; CPU[i]->currentQueue = 1; mfbq_queue1[j] = CPU[i]; context_switches++; j++; CPU[i] = NULL; //free the CPU for another process //second level } else if (CPU[i]->quantumRemaining == 0 && CPU[i]->currentQueue == 1) { //doesn't finish within those two time slices fprintf(log_file, "Second time slice is met\n"); fprintf(log_file, "PID:%d\tLength:%d\n", CPU[i]->pid, CPU[i]->bursts[CPU[i]->currentBurst].length); CPU[i]->quantumRemaining = INT32_MAX; // the maximum time //CPU[i]->quantumRemaining = MAX_TIME; CPU[i]->currentQueue = 2; context_switches++; mfbq_queue2[k] = CPU[i]; k++; CPU[i] = NULL; //free the cpu for another process //Promotion } else if (CPU[i]->bursts[CPU[i]->currentBurst].length < time_slice) { fprintf(log_file, "Promotion 1 defaults to FCFS . . . . .\n"); fprintf(log_file, "PID:%d\tLength:%d\n", CPU[i]->pid, CPU[i]->bursts[CPU[i]->currentBurst].length); CPU[i]->currentQueue = 0; // priority level remains unchanged promoted_queue[l] = CPU[i]; l++; CPU[i] = NULL; } else if (CPU[i]->bursts[CPU[i]->currentBurst].length < time_slice_1) { fprintf(log_file, "Promotion 2 defaults to FCFS . . . .\n"); fprintf(log_file, "PID:%d\tLength:%d\n", CPU[i]->pid, CPU[i]->bursts[CPU[i]->currentBurst].length); CPU[i]->currentQueue = 0; // priority level remains unchanged promoted_queue_2[m] = CPU[i]; m++; CPU[i] = NULL; } } } /* Add all interrupt process back to various queues depending on their priority*/ qsort(mfbq_queue1, j, sizeof (process*), compareProcessIds); for (x = 0; x < j; x++) { enqueueProcess(&level_one, mfbq_queue1[x]); } qsort(mfbq_queue2, k, sizeof (process*), compareProcessIds); for (x = 0; x < k; x++) { enqueueProcess(&second_level, mfbq_queue2[x]); } qsort(promoted_queue, l, sizeof (process*), compareProcessIds); for (x = 0; x < l; x++) { enqueueProcess(&readyQueue, promoted_queue[x]); } qsort(promoted_queue_2, m, sizeof (process*), compareProcessIds); for (x = 0; x < m; x++) { enqueueProcess(&readyQueue, promoted_queue_2[x]); } }
int main(int argc, char *argv[]) { int waitingIndex; setUpProcesses(); totalProcesses = numberOfProcesses; //error management of invalid number of processes quantum = readInt(&argv[1]); if (checkErrors(quantum) == -1) { error("Invalid number of processes"); return -1; } //sort processes by arrival time and priority qsort(processes, numberOfProcesses, sizeof(process), compareByArrival); initializeProcessQueue(&readyQueue); initializeProcessQueue(&waitingQueue); setupCPUS(); //set the quantum slice if (checkErrors(quantum) == -2) { error_bad_quantum(); return -1; } while (1) { preparePreQueue(); // if finished cpu burst, move to waiting queue if it is not the last cpu burst int cpuIndex = 0; int cpuUse = 0; // set up the current CpuBursts cpuBurstAllocation(cpuIndex, cpuUse); //sort waiting queue by processes priority int waitingQueueSize = waitingQueue.size; // iterate over queue where there are no indexes, and are waiting for (waitingIndex = 0; waitingIndex < waitingQueueSize; waitingIndex++) { dequeueEnqueueWaitingBusts(waitingIndex, waitingQueueSize); } //sort preReadyQueue and queue the expired time slices to the ready queue qsort(preReadyQueue, preReadyQueueSize, sizeof(process*), comparePIDs); qsort(tempProcess, tempProcessSize, sizeof(process*), comparePIDs); int j; //previous processes with expired time slices go into ready queue first as is in fifo for (j = 0; j < tempProcessSize; j++) { enqueueProcess(&readyQueue, tempProcess[j]); } tempProcessSize = 0; //enqueue everything in the ready queue for (j = 0; j < preReadyQueueSize; j++) { enqueueProcess(&readyQueue, preReadyQueue[j]); } preReadyQueueSize = 0; //assign the available cpu to first process of ready queue for (cpuIndex = 0; cpuIndex < NUMBER_OF_PROCESSORS; cpuIndex++) { conditionalCPUProcessQueue(cpuIndex, preReadyQueueSize, tempProcessSize); } //update burst of all processes in every queue int r; for (r = 0; r < readyQueue.size; r++) { updateQueues(); } if (cpuUse == 0 && waitingQueue.size == 0 && (numberOfProcesses - nextProcess) == 0) { break; // exit loop if no cpu in use or no running processes and none in waiting queue } timer++; //increment one time unit for each loop } setUpPrintVariables(); //print values printf("Average waiting time : %.2f units\n", totalWaitingTime/(double)numberOfProcesses); printf("Average turnaround Time : %.2f units\n", totalTurnAroundTime/(double)numberOfProcesses); printf("Time all processes finished : %d\n", timer); printf("Average CPU utilization : %.1f%%\n", 100.0 * cpuUseTotal / timer); printf("Number of context switches : %d\n", context); printf("PID(s) of last process(es) to finish : %d\n", lastPID); return 0; }
void Wait_For_Clock (pcb_t *attuale){ if(P(PSEUDO_CLOCK_SEM, attuale)){ enqueueProcess(attuale); } }
void Get_CPU_Time(pcb_t *attuale){ attuale->p_s.reg_v0 = (attuale->cpu_time += (GET_TODLOW - (attuale->systemTOD))); enqueueProcess(attuale); }