#include #include #include "sched_mfq.h" using namespace std; SchedMFQ::SchedMFQ(vector argn) { // MFQ recibe los quantums por parámetro n_colas = argn.size() - 1; for (uint i = 0; i < n_colas; i++) { v_queues.push_back(queue()); v_queues_quantum.push_back(argn[i + 1]); } } SchedMFQ::~SchedMFQ() { } void SchedMFQ::load(int pid) { // Inicializo nuevo proceso process p = process(); p.queue = 0; p.quantum_count = 0; p.state = READY; // Lo cargo en la lista de procesos y en la cola 0 v_process[pid] = p; v_queues[0].push(pid); } void SchedMFQ::unblock(int pid) { process& p = v_process[pid]; p.state = READY; p.quantum_count = 0; // Si no está en la cola 0, lo bajo una mas if (p.queue > 0) { p.queue--; } // Lo vuelvo a encolar v_queues[p.queue].push(pid); } uint SchedMFQ::next_pid() { for (uint q = 0; q < n_colas; q++) { // Si hay un elemento en la cola lo leo if (!v_queues[q].empty()) { int pid = v_queues[q].front(); v_queues[q].pop(); return pid; } } return IDLE_TASK; } /** * Cambia a la próxima tarea disponible y la activa como running */ int SchedMFQ::switch_task() { int cur_pid = next_pid(); if (cur_pid != IDLE_TASK) { process* next_process = &(v_process[cur_pid]); next_process->state = RUNNING; } return cur_pid; } int SchedMFQ::tick(int core, const enum Motivo m) { int cur_pid = current_pid(core); // Si estoy en idle, busco la siguiente tarea y la pongo como running if (cur_pid == IDLE_TASK) { return switch_task(); } // Cargo proceso actual process* cur_process = &(v_process[cur_pid]); uint cur_queue = cur_process->queue; switch (m) { case TICK: cur_process->quantum_count++; // Si ya cumplió el quantum if (cur_process->quantum_count >= v_queues_quantum[cur_queue]) { cur_process->quantum_count = 0; cur_process->state = READY; // Lo muevo la siguiente cola, si se puede if (cur_process->queue < n_colas - 1) { cur_process->queue++; } v_queues[cur_process->queue].push(cur_pid); cur_pid = switch_task(); } break; case BLOCK: cur_process->quantum_count = 0; cur_process->state = BLOCKED; cur_pid = switch_task(); break; case EXIT: v_process.erase(cur_pid); cur_pid = switch_task(); break; } return cur_pid; }