/** 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--;
		}
	}

}
Exemple #2
0
// 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);
  }
}
/* 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);
        }
    }
}
/* 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);
        }
    }
}
/**	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);
		}
	}

}
Exemple #7
0
// 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);
}
/**
 * Gets the next ready process to be fed into the Cpu
 */
process *get_next_sch_process() {
    if (readyQueue.size == 0) {
        return NULL;
    }
    process *cpu_ready = readyQueue.front->data;
    dequeueProcess(&readyQueue);
    return cpu_ready;
}
/**
 * Gets the next ready process to be fed into the Cpu
 */
process *get_next_sch_process() {
    process *cpu_ready;
    if (readyQueue.size > 0) {
        cpu_ready = readyQueue.front->data;
        dequeueProcess(&readyQueue);
        return cpu_ready;
    } else if (level_one.size > 0) {
        cpu_ready = level_one.front->data;
        dequeueProcess(&level_one);
        return cpu_ready;
    } else if (second_level.size > 0) {
        cpu_ready = second_level.front->data;
        dequeueProcess(&second_level);
        return cpu_ready;
    } else {
        return NULL;
    }
}
/* 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);
    }
}
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 */
    }
}
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 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);
        }
    }
}
Exemple #16
0
// goes through everything in the ready queue and sets up the actual quantum time allocated to process
// this then dequeues out the ready queue and bursts the current burst of the step
void conditionalCPUProcessQueue(int cpuIndex, int preReadyQueueSize, int tempProcessSize) {
  if (cpus[cpuIndex] == NULL) {
    if (readyQueue.size == 0) {
      cpus[cpuIndex] = NULL;
    } else { 
      //set quantum time, subtract one for current step
      if (readyQueue.front->data->startTime == 0) {
        readyQueue.front->data->startTime = timer;
      }
      readyQueue.front->data->quantumRemaining = quantum - 1;
      cpus[cpuIndex] = readyQueue.front->data;
      dequeueProcess(&readyQueue);
      cpus[cpuIndex]->bursts[cpus[cpuIndex]->currentBurst].step++;

      cpuUse++;
      cpuUseTotal++;
    }

  }
}
Exemple #17
0
// Simulates one processing cycle
// @par: int    current time (quantum)
// @par: int    flag if real time queue updated
// @ret: none
void doProcessing(int time, int rtUpdated) {
    printf("------------------------------------------------------- PROCESSOR CYCLE -------------------------------------------------------\n");

    // Check if current process in a queue
    if (host.currentProcess != NULL) {
        // If current process not zero then not realtime
        if (host.currentProcess->priority != 0) {
            // If realtime queue was updated, move current process back to its queue and keep the remaining timesplice on it
            if (rtUpdated) {
                host.currentProcess->state = SUSPENDED;
                printf("* SUSPENDED pid: %d\n", host.currentProcess->pid);

                enqueueToPriority(host.currentProcess);

                // Enqueue the realtime process
                if (realTimeQueue->process != NULL) {
                    host.currentProcess = realTimeQueue->process;
                    host.currentProcess->timeSpliceLeft = host.currentProcess->remainingTime;
                    dequeueProcess(&realTimeQueue);
                }
            }
        }
    } else {
        // Processor does not have a process currently
        printf("NO PROCESS RUNNING, SEARCHING FOR ANOTHER...\n");

        if (rtUpdated) {
            // Enqueue the realtime process
            if (realTimeQueue) {
                if (realTimeQueue->process != NULL) {
                    host.currentProcess = realTimeQueue->process;
                    host.currentProcess->timeSpliceLeft = host.currentProcess->remainingTime;
                    dequeueProcess(&realTimeQueue);
                }
            }
        } else if (p1Queue) {
            if (p1Queue->process != NULL) {
                host.currentProcess = p1Queue->process;
                dequeueProcess(&p1Queue);
                host.currentProcess->timeSpliceLeft = P1_TIMEQUANTUM;
            }
        } else if (p2Queue) {
            if (p2Queue->process != NULL) {
                host.currentProcess = p2Queue->process;
                dequeueProcess(&p2Queue);
                host.currentProcess->timeSpliceLeft = P2_TIMEQUANTUM;
            }
        } else if (p3Queue) {
            if (p3Queue->process != NULL) {
                host.currentProcess = p3Queue->process;
                dequeueProcess(&p3Queue);
                host.currentProcess->timeSpliceLeft = P3_TIMEQUANTUM;
            }
        } else {
            return;
        }
    }

    // Actual processing goes here
    if (host.currentProcess != NULL) {
        host.currentProcess->state = RUNNING;
        host.currentProcess->timeSpliceLeft--;
        host.currentProcess->remainingTime--;
        printf("* RUNNING pid: %d\n", host.currentProcess->pid);

        if (VERBOSE) printf("Time splice left in this queue: %d, total remaining time: %d\n", host.currentProcess->timeSpliceLeft, host.currentProcess->remainingTime);

        if (host.currentProcess->remainingTime == 0) {
            // Process has no time splice left in this queue, terminate the process
            freeHostResources(host.currentProcess);
            host.currentProcess->state = TERMINATED;
            printf("* TERMINATED pid: %d, process completed!\n", host.currentProcess->pid);
            free(host.currentProcess);
            host.currentProcess = NULL;
        } else if (host.currentProcess->timeSpliceLeft == 0) {
            // Round robin queuing
            if (host.currentProcess->priority < 3 && host.currentProcess->priority >= 1) {
                host.currentProcess->priority++;
                enqueueToPriority(host.currentProcess);
                host.currentProcess = NULL;
            } else if (host.currentProcess->priority >= 3) {
                host.currentProcess->timeSpliceLeft = P3_TIMEQUANTUM;
                host.currentProcess->priority = 1;
                enqueueToPriority(host.currentProcess);
                host.currentProcess = NULL;
            }
        }
    }
}
Exemple #18
0
// 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;
}
/* simulates the CPU scheduler, fetching and dequeuing the next scheduled
   process from the ready queue.  it then returns a pointer to this process,
   or NULL if no suitable next process exists. */
process *nextScheduledProcess(void) {
    if (readyQueue.size == 0) return NULL;
    process *result = readyQueue.front->data;
    dequeueProcess(&readyQueue);
    return result;
}