#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

/*
 * Insercao de processos em NPRI Ready Queues, uma por prioridade
 * Remocao por ordem de prioridade decrescente
 *
 * Jose Rogado
 */

#define NPRI 10

// Estrutura para armazenar os processos
typedef struct proc {
  int pid;
  int pri;
  time_t time;
  struct proc *next;
  struct proc *prev;
} proc_t;

// Estrutura Inicio de Lista
typedef struct queue_head {
  struct proc *next;
  struct proc *last;
} queue_t;

// Tabela das Ready Queues
queue_t array_queue[NPRI];

void selecao(void);

int main()
{
  int i, pri, ret, nprocs=0, pid;
  proc_t *p,*r;
  queue_t *q;

  // Inicializacao a zero dos elementos da tabela
  memset(array_queue, 0, NPRI * sizeof(queue_t));

  while(1){
    printf("Insira a prioridade do Processo %d: ", nprocs);
    ret = scanf("%d",&pri);
    if (ret == EOF) { // Ctrl-D
       break;
    }
    if(pri>9) pri=9;

    if(pri<0) pri=0;

    p = (proc_t *) calloc(1, sizeof( struct proc ) );

    p->pri = pri;
    p->pid = nprocs++;

    q = &array_queue[pri];

    if (q->next == 0) {
      q->next = p;
      q->last = p;
    } else {
      r = q->last;
      r->next = p;
      q->last = p;
    }
    //printf("Prioridade do Processo Inserido: %d\n",p->pri);
    //printf("Numero do Processo: %d\n",p->pid);
  }

  // Seleccionar todos os processos inseridos por ordem de prioridade
  for (i = 0; i < nprocs; i++)
    selecao();
}

void selecao(){

  int k = 0;
  proc_t *p;
  queue_t *q;

  /*
   * Procurar o processo de maior prioridade nas ready queues
   */
  for (k = 0; k < NPRI; k++) {
    q = &array_queue[k];
    if (q->next != NULL)
      // O processo seleccionado e o primeiro
      // da queue de maior prioridade
      break;
  }
  // Retirar o processo de maior prioridade da lista
  p = q->next;
  q->next = p->next;
  printf ("\nProcesso Seleccionado: pid: %d  pri: %d\n", p->pid , p->pri);
  free(p);
}

