miércoles, 23 de enero de 2008

Programa que simula una cola de Impresión en lenguaje ADA

* Descargar el fichero prac06.ada y completar el código que falta en base a los siguientes requisitos. Desarrollar un programa que simule una Cola de Impresión, —recepción en la Cola y envío de trabajos a la impresora—. La Cola de Impresión deberá implementarse en una Cola Circular si es en memoria estática, o en memoria dinámica, en cualquier caso de tamaño 20. Tendrá asímismo dos indicadores que nos permitirán localizar el primer trabajo que se va a imprimir y cuál es el último de la Cola. En la Cola de Impresión se almacenará exclusivamente el número de páginas de cada trabajo.
* Para el desarrollo de tal simulación se implementarán dos tareas concurrentes: LlenaCola y VacíaCola, la primera se entrega implementada en el fichero prac06.ada y simula el envío aleatorio de trabajos a la Cola de Impresión , indicando el número de páginas también de forma aleatoria; la segunda deberá simular un proceso concurrente que está continuamente escaneando la Cola de Impresión y en caso de existir algún trabajo pendiente de imprimir se eliminará de dicha Cola —se supone el envío a la impresora—. No se podrá enviar a la impresora —eliminación del primero de la Cola— otro trabajo hasta que el anterior termine. La impresora tiene una velocidad de impresión de 50 páginas por segundos.
* Se ilustra un ejemplo del estado de la Cola de Impresión, donde el siguiente trabajo a imprimir posee 67 páginas y por lo tanto después de ser eliminado no podrá eliminarse el siguiente hasta, al menos, pasados 0.02 * 67 segundos.



WITH Ada.Text_IO,Ada.Integer_Text_IO,Ada.Numerics.Discrete_Random,Unchecked_Deallocation;
USE Ada.Text_IO,Ada,Ada.Integer_Text_IO;

PROCEDURE Principal IS
subtype Páginas is Integer range 1..100;
package RandomPáginas is new Ada.Numerics.Discrete_Random (Páginas);
use RandomPáginas;
subtype Duración is Integer range 1..100;
package RandomDuración is new Ada.Numerics.Discrete_Random (Duración);
use RandomDuración;
------------------------------------
type Nodo;
type PCola is access Nodo;
type Nodo is record
Info: Integer;
Sig: PCola:=null;
end record;

type Cola is record
Pri: PCola:=null;
Ult: PCola:=null;
end record;
---------------------------------------


-- Implemente la especificación de las Tareas.
task type LlenaCola;
task type VacíaCola;

-- Implemente la especificación de MonitorCola.
protected type MonitorCola is
entry AñadirTrabajo(NumeroPaginas: in Páginas);
entry ImprimirTrabajo(NumPaginas: out integer);
procedure mostrar;
private
C: Cola;
EnCola: Integer:=0;
end MonitorCola;


procedure Libera is new Unchecked_Deallocation(Nodo,PCola);

ColaImpresión : MonitorCola; -- Variable de tipo protegido (protected).


-- Implemente el cuerpo de MonitorCola.
--------------------------------------------------------------------------
protected body MonitorCola is
----------------------------------------------
entry AñadirTrabajo(NumeroPaginas: in Páginas) when EnCola < 20 is
begin
if EnCola=0 then
C.Pri:=new Nodo;
C.Pri.Info:=NumeroPaginas;
C.Ult:=C.Pri;
else
C.Ult.Sig:=new Nodo;
C.Ult:=C.Ult.Sig;
C.Ult.Info:=NumeroPaginas;
end if;
EnCola:=EnCola+1;
Mostrar;
end AñadirTrabajo;
----------------------------------------------
entry ImprimirTrabajo(NumPaginas: out integer) when EnCola>0 is
Aux: PCola:=C.Pri;


begin
C.Pri:=C.Pri.Sig;
NumPaginas:=Aux.Info;
Libera(Aux);
EnCola:=EnCola-1;
Mostrar;
end ImprimirTrabajo;
----------------------------------------------
----------------------------------------------
procedure mostrar is
Aux: PCola:=C.Pri;
begin
Put("Cola[");
Put(EnCola,2);
Put("]->");
while Aux/=null loop
Put(Aux.Info,3);
Aux:=Aux.Sig;
if Aux/=null then
Put(",");
end if;
end loop;
New_Line;
end Mostrar;
----------------------------------------------
end MonitorCola;

--------------------------------------------------------------------------
-- Implemente el cuerpo de la Tarea VacíaCola.
task body VacíaCola is
N: Integer;
begin
loop
ColaImpresión.ImprimirTrabajo(N);
delay 0.02*N;
end loop;
end VacíaCola;


-- Implementación del cuerpo de LLenaCola. Esta tarea envía trabajos a la cola de impresión
-- con una frecuencia de 0.7 trabajos por segundo como media. Asímismo dichos trabajos poseen
-- 50 páginas como media. Si se desea puede modificar el número 35 para comprobar como se llena o
-- se mantiene vacía la cola, dado que se modifica la frecuencia de envío de los trabajos.


TASK BODY LlenaCola IS
G1: RandomDuración.generator;
G2: RandomPáginas.generator;
BEGIN
reset(G1);
reset(G2);
LOOP
ColaImpresión.AñadirTrabajo(random(G2));
delay Duration(1);
END LOOP;
END LlenaCola;


-- Variables de tipo tarea (task).
A:LlenaCola;
B:VacíaCola;
BEGIN
null;
END Principal;