|
@@ -6,143 +6,106 @@ using namespace std;
|
|
|
|
|
|
|
|
SchedMFQ::SchedMFQ(vector<int> argn) {
|
|
SchedMFQ::SchedMFQ(vector<int> argn) {
|
|
|
// MFQ recibe los quantums por parámetro
|
|
// MFQ recibe los quantums por parámetro
|
|
|
- n_colas = argn.size()-1;
|
|
|
|
|
- q_cola = new uint[n_colas];
|
|
|
|
|
|
|
+ n_colas = argn.size() - 1;
|
|
|
|
|
|
|
|
- for( uint i = 0; i < n_colas ;i++ ){
|
|
|
|
|
- q_cola[i] = argn[1+i];
|
|
|
|
|
- v_cola.push_back(std::map<int,process>());
|
|
|
|
|
|
|
+ for (uint i = 0; i < n_colas; i++) {
|
|
|
|
|
+ v_queues.push_back(queue<uint>());
|
|
|
|
|
+ v_queues_quantum.push_back(argn[i + 1]);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
SchedMFQ::~SchedMFQ() {
|
|
SchedMFQ::~SchedMFQ() {
|
|
|
- delete[] q_cola;
|
|
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void SchedMFQ::load(int pid) {
|
|
void SchedMFQ::load(int pid) {
|
|
|
- v_cola[0][pid].state=READY; //Cargo PID en la cola de mayor prioridad
|
|
|
|
|
|
|
+ // 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) {
|
|
void SchedMFQ::unblock(int pid) {
|
|
|
- uint p_q=pid_queue(pid);
|
|
|
|
|
- v_cola[p_q][pid].state = READY;
|
|
|
|
|
- v_cola[p_q][pid].quantum_count = 0;
|
|
|
|
|
|
|
+ process& p = v_process[pid];
|
|
|
|
|
+ p.state = READY;
|
|
|
|
|
+ p.quantum_count = 0;
|
|
|
|
|
|
|
|
- if(p_q > 0) { //Hay una cola "mejor" para ir; lo llevo
|
|
|
|
|
- v_cola[p_q-1][pid]=v_cola[p_q][pid];
|
|
|
|
|
- v_cola[p_q].erase(pid);
|
|
|
|
|
|
|
+ // 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::pid_queue(int pid){
|
|
|
|
|
- for( uint i = 0; i < n_colas; i++ )
|
|
|
|
|
- if ( v_cola[i].count(pid) == 1) //Solo hay 0/1 key en un map
|
|
|
|
|
- return i;
|
|
|
|
|
-
|
|
|
|
|
- /*
|
|
|
|
|
- cout << "WHAT THE FUCK " << pid << endl;
|
|
|
|
|
- for( uint i = 0; i < n_colas; i++ )
|
|
|
|
|
- cout << "size cola " << i << " = " << v_cola[i].size() << endl;
|
|
|
|
|
- */
|
|
|
|
|
- return 65535; // ??
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-int SchedMFQ::ready_at(uint qn, int cur_pid){
|
|
|
|
|
- if (v_cola[qn].size() == 0)
|
|
|
|
|
- return -1;
|
|
|
|
|
-
|
|
|
|
|
- for (it_type it = ++v_cola[qn].find(cur_pid); it != v_cola[qn].end(); it++) {
|
|
|
|
|
- //cout << "Mirando al pid " << it->first << endl;
|
|
|
|
|
- if (it->second.state == READY)
|
|
|
|
|
- return it->first;
|
|
|
|
|
- }
|
|
|
|
|
- for (it_type it = v_cola[qn].begin(); it != v_cola[qn].find(cur_pid); it++) {
|
|
|
|
|
- //cout << "Mirando al pid " << it->first << endl;
|
|
|
|
|
- if (it->second.state == READY)
|
|
|
|
|
- return it->first;
|
|
|
|
|
- }
|
|
|
|
|
- if(v_cola[qn][cur_pid].state==READY)
|
|
|
|
|
- return cur_pid;
|
|
|
|
|
-
|
|
|
|
|
- return IDLE_TASK;
|
|
|
|
|
-}
|
|
|
|
|
-uint SchedMFQ::next_pid(int cur_pid){
|
|
|
|
|
- for( uint q = 0; q < n_colas; q++ ){
|
|
|
|
|
- //cout << "Mirando en la pila " << q << endl;
|
|
|
|
|
- int p = ready_at(q,cur_pid);
|
|
|
|
|
- if (p != -1)
|
|
|
|
|
- return p; //Algun proceso listo
|
|
|
|
|
|
|
+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;
|
|
return IDLE_TASK;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void SchedMFQ::mostrar_estados(){
|
|
|
|
|
- //cout << "RDY: " << READY << ", RNING: " << RUNNING << ", BLK: " << BLOCKED << endl;
|
|
|
|
|
- for( uint q = 0; q < n_colas; q++ ){
|
|
|
|
|
- //cout << "Cola " << q << ", size: " << v_cola[q].size() << endl;
|
|
|
|
|
- for (it_type it = v_cola[q].begin(); it != v_cola[q].end(); it++) {
|
|
|
|
|
- cout << "["<< q <<"]PID: " << it->first << ", STATE: " << it->second.state << endl;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 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 SchedMFQ::tick(int core, const enum Motivo m) {
|
|
|
- uint switch_process = 0;
|
|
|
|
|
int cur_pid = current_pid(core);
|
|
int cur_pid = current_pid(core);
|
|
|
- uint p_q;
|
|
|
|
|
- //cout << "(start tick) PID at core " << core << " = " << cur_pid << endl;
|
|
|
|
|
- if (cur_pid == IDLE_TASK){ //FIXME repito el codigo abajo en switch_process
|
|
|
|
|
- cur_pid = next_pid(cur_pid);
|
|
|
|
|
- if (cur_pid != IDLE_TASK){
|
|
|
|
|
- p_q = pid_queue(cur_pid);
|
|
|
|
|
- v_cola[p_q][cur_pid].state = RUNNING;
|
|
|
|
|
- }
|
|
|
|
|
- return cur_pid;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Si estoy en idle, busco la siguiente tarea y la pongo como running
|
|
|
|
|
+ if (cur_pid == IDLE_TASK) {
|
|
|
|
|
+ return switch_task();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- p_q = pid_queue(cur_pid);
|
|
|
|
|
- if (p_q == 65535) //FIXME ?
|
|
|
|
|
- return IDLE_TASK;
|
|
|
|
|
- process* cur_process=&(v_cola[p_q][cur_pid]);
|
|
|
|
|
|
|
+ // Cargo proceso actual
|
|
|
|
|
+ process* cur_process = &(v_process[cur_pid]);
|
|
|
|
|
+ uint cur_queue = cur_process->queue;
|
|
|
|
|
|
|
|
switch (m) {
|
|
switch (m) {
|
|
|
case TICK:
|
|
case TICK:
|
|
|
cur_process->quantum_count++;
|
|
cur_process->quantum_count++;
|
|
|
- if (cur_process->quantum_count >= q_cola[p_q]) {
|
|
|
|
|
- cout << "pid: " << cur_pid << " con q >" << q_cola[p_q] << endl;
|
|
|
|
|
- switch_process = 1;
|
|
|
|
|
- cur_process->state = READY;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Si ya cumplió el quantum
|
|
|
|
|
+ if (cur_process->quantum_count >= v_queues_quantum[cur_queue]) {
|
|
|
cur_process->quantum_count = 0;
|
|
cur_process->quantum_count = 0;
|
|
|
- //cout << "Marcando a cur_pid("<< cur_pid<<") como READY (>quantum)" << endl;
|
|
|
|
|
- if(p_q < (n_colas - 1)) { //Hay una cola "peor" para ir; lo llevo
|
|
|
|
|
- mostrar_estados();
|
|
|
|
|
- v_cola[p_q+1][cur_pid]=*cur_process;
|
|
|
|
|
- cout << "Moviendo pid: " << cur_pid << " a cola con q=" << q_cola[p_q+1] << endl;
|
|
|
|
|
- v_cola[p_q].erase(cur_pid);
|
|
|
|
|
- mostrar_estados();
|
|
|
|
|
|
|
+ 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;
|
|
break;
|
|
|
case BLOCK:
|
|
case BLOCK:
|
|
|
- switch_process = 1;
|
|
|
|
|
|
|
+ cur_process->quantum_count = 0;
|
|
|
cur_process->state = BLOCKED;
|
|
cur_process->state = BLOCKED;
|
|
|
|
|
+ cur_pid = switch_task();
|
|
|
break;
|
|
break;
|
|
|
case EXIT:
|
|
case EXIT:
|
|
|
- switch_process = 1;
|
|
|
|
|
- //cout << v_cola[p_q].size() << endl;
|
|
|
|
|
- //cout << "borro pid: " << cur_pid << endl;
|
|
|
|
|
- v_cola[p_q].erase(cur_pid);
|
|
|
|
|
- //cout << v_cola[p_q].size() << endl;
|
|
|
|
|
|
|
+ v_process.erase(cur_pid);
|
|
|
|
|
+ cur_pid = switch_task();
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- //mostrar_estados();
|
|
|
|
|
|
|
|
|
|
- if (switch_process) {
|
|
|
|
|
- cur_pid = next_pid(cur_pid);
|
|
|
|
|
- if (cur_pid != IDLE_TASK){
|
|
|
|
|
- p_q = pid_queue(cur_pid);
|
|
|
|
|
- v_cola[p_q][cur_pid].state = RUNNING;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
return cur_pid;
|
|
return cur_pid;
|
|
|
}
|
|
}
|