sched_mfq.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <map>
  2. #include <iostream>
  3. #include "sched_mfq.h"
  4. using namespace std;
  5. SchedMFQ::SchedMFQ(vector<int> argn) {
  6. // MFQ recibe los quantums por parámetro
  7. n_colas = argn.size() - 1;
  8. for (uint i = 0; i < n_colas; i++) {
  9. v_queues.push_back(queue<uint>());
  10. v_queues_quantum.push_back(argn[i + 1]);
  11. }
  12. }
  13. SchedMFQ::~SchedMFQ() {
  14. }
  15. void SchedMFQ::load(int pid) {
  16. // Inicializo nuevo proceso
  17. process p = process();
  18. p.queue = 0;
  19. p.quantum_count = 0;
  20. p.state = READY;
  21. // Lo cargo en la lista de procesos y en la cola 0
  22. v_process[pid] = p;
  23. v_queues[0].push(pid);
  24. }
  25. void SchedMFQ::unblock(int pid) {
  26. process& p = v_process[pid];
  27. p.state = READY;
  28. p.quantum_count = 0;
  29. // Si no está en la cola 0, lo bajo una mas
  30. if (p.queue > 0) {
  31. p.queue--;
  32. }
  33. // Lo vuelvo a encolar
  34. v_queues[p.queue].push(pid);
  35. }
  36. uint SchedMFQ::next_pid() {
  37. for (uint q = 0; q < n_colas; q++) {
  38. // Si hay un elemento en la cola lo leo
  39. if (!v_queues[q].empty()) {
  40. int pid = v_queues[q].front();
  41. v_queues[q].pop();
  42. return pid;
  43. }
  44. }
  45. return IDLE_TASK;
  46. }
  47. /**
  48. * Cambia a la próxima tarea disponible y la activa como running
  49. */
  50. int SchedMFQ::switch_task() {
  51. int cur_pid = next_pid();
  52. if (cur_pid != IDLE_TASK) {
  53. process* next_process = &(v_process[cur_pid]);
  54. next_process->state = RUNNING;
  55. }
  56. return cur_pid;
  57. }
  58. int SchedMFQ::tick(int core, const enum Motivo m) {
  59. int cur_pid = current_pid(core);
  60. // Si estoy en idle, busco la siguiente tarea y la pongo como running
  61. if (cur_pid == IDLE_TASK) {
  62. return switch_task();
  63. }
  64. // Cargo proceso actual
  65. process* cur_process = &(v_process[cur_pid]);
  66. uint cur_queue = cur_process->queue;
  67. switch (m) {
  68. case TICK:
  69. cur_process->quantum_count++;
  70. // Si ya cumplió el quantum
  71. if (cur_process->quantum_count >= v_queues_quantum[cur_queue]) {
  72. cur_process->quantum_count = 0;
  73. cur_process->state = READY;
  74. // Lo muevo la siguiente cola, si se puede
  75. if (cur_process->queue < n_colas - 1) {
  76. cur_process->queue++;
  77. }
  78. v_queues[cur_process->queue].push(cur_pid);
  79. cur_pid = switch_task();
  80. }
  81. break;
  82. case BLOCK:
  83. cur_process->quantum_count = 0;
  84. cur_process->state = BLOCKED;
  85. cur_pid = switch_task();
  86. break;
  87. case EXIT:
  88. v_process.erase(cur_pid);
  89. cur_pid = switch_task();
  90. break;
  91. }
  92. return cur_pid;
  93. }