Sei sulla pagina 1di 9

EXAMEN SISTEMAS INFORMATICOS DE TIEMPO REAL.

29 de Enero de 2001
Pregunta 1 (1.5 p): Explicar, en un modelo de comunicacin por memoria compartida, cual es el
problema que puede suceder al acceder varias tareas ejecutndose concurrentemente a una variable
compartida y porque. Exponer que solucin nos proporciona Ada 95 y como funciona.

Solucin
Supongamos dos tareas que comparten la variable X, y que ambos quieren realizar una operacin sobre
Xx En muchos computadores esto no se realiza como una operacin atmica, sino que supone un
conjunto de operaciones a nivel de procesador, normalmente:
?? Cargar el valor de la variable X en un registro
?? Incrementar/decrementar el valor del registro
?? Almacenar el valor resultante en la variable X
Dado que estas operaciones no se puede garantizar que se ejecuten indivisiblemente el resultado puede ser
incorrecto. Veamos una posible secuencia donde dos tareas acceden a la variable X, P1 para incrementar
en 1 su valor y P2 para decrementarla tambin en 1. La lgica nos dice que fuera cual fuera el orden en
que se ejecutaran las instrucciones ( primero X:=X+1 y despues X:=X-1, o al contrario), el valor final de
X debera ser el mismo. Veamos una posible ejecucin.
Tiempo
Tarea
Operacin
Registro 1
Registro 2
Variable X
T1
5
T2
P1
Mov X,reg1
5
5
T3
P1
Inc reg1
6
5
T4
P2
Mov X,reg2
6
5
5
T5
P2
Dec reg2
6
4
5
T6
P1
Mov reg1,X
6
4
6
T7
P2
Mov reg2,X
6
4
4 ERROR!
Podemos ver que el resultado no es el esperado. Tal como nos dicta la lgica el resultado de la ejecucin
paralela (concurrente) de estas instrucciones debe ser el mismo en todos los casos.
La solucin aportada en Ada son los tipos protegidos
Un tipo protegido de Ada encapsula unos datos, proporcionando un acceso a los mismos mediante
subprogramas (function o procedure) y mediante entradas (entry) protegidos. El lenguaje garantiza que
dichos subprogramas y entradas se ejecutaran de forma que la informacin es actualizada en modo
excluyente. Condiciones de sincronizacin pueden obtenerse mediante el uso de guardas boolenas en las
entradas, las cuales debern ser verdaderas para poder ejecutar el cdigo asociado a la misma.
Un tipo protegido tiene una parte de especificacin y una implementacin
Pregunta 2 (1.0 p): Implementar una tarea peridica de periodo 500 milisegundos y con un plazo limite
del bucle de 250 de milisegundos. Incluir las llamadas necesarias a los paquetes que proporcionan el reloj
adecuado.

Solucin
with Ada.Real_Time;
use Ada.Real_Time;
task body Limitada is
Plazo : constant Time_Span := Milliseconds (250);
Periodo : constant Time_Span := Milliseconds (500);
Siguiente:Time;
Vez
:
Integer
:= 0;
Ok
:
Boolean;
begin
Main:
Siguiente:=clock;
loop
Vez:=Vez+1;
select
delay until (siguiente+plazo);
then
abort
Ok:=Cuenta(Vez);
end select;
siguiente:=siguiente+periodo;
delay until siguiente;
end loop Main;

end Limitada;

Pregunta 4 (3 p): . Sea el sistema mostrado en la figura cuya implementacin es la siguiente:


with calendar;use calendar;
package ALMACENES is
type PIEZA is
record
tipo:INTEGER;
numero:INTEGER;
Tiempo_generacion:TIME;
Tiempo_salida: TIME;
end record;
type TAMPON is array (INTEGER range <>) of PIEZA;
protected type ALMACEN(N:integer) is
entry NO_VACIA;
entry NO_LLENA;
procedure INICIALIZAR;
procedure ESTADO_ALMACEN;
entry ANYADIR(ITEM: in PIEZA;Tp: in NATURAL);
entry SACAR (ITEM: out PIEZA);
function TIPO(gid: in INTEGER) return BOOLEAN;
function VER_TIEMPO return TIME;
private
num, primero, ultimo: INTEGER ;
cola: TAMPON(1..N);
end ALMACEN;
ALMACEN_LLENO, ALMACEN_VACIO: exception;
end ALMACENES;
WITH Gnat.IO;USE Gnat.IO;
WITH Ada.Integer_Text_IO;
with CALENDAR;use CALENDAR;
package body ALMACENES is
protected body almacen is
entry NO_VACIA when NUM>0 is
begin
null;
end NO_VACIA;
entry NO_LLENA when NUM<N is
begin
null;
end NO_LLENA;
function TIPO(gid: in integer) return BOOLEAN is
begin
return cola(ultimo).tipo=gid;
end TIPO;
procedure INICIALIZAR is
begin
primero := 1;
ultimo := 1;
Num := 0;
end INICIALIZAR;
procedure ESTADO_ALMACEN is
begin
gnat.io.put("..");gnat.io.put(num);gnat.io.put("..");
gnat.io.put(cola(ultimo).tipo);gnat.io.put("-");
gnat.io.put(cola(ultimo).numero);gnat.io.put("
");
end ESTADO_ALMACEN;
entry ANYADIR(item: in PIEZA;Tp: in NATURAL) when Num<N is
begin
cola(primero) := item;
cola(primero).tiempo_salida:=clock+duration(Tp);
primero := (primero mod N) + 1;
Num := Num + 1;
end ANYADIR;
entry SACAR (item: out PIEZA) when Num>0 is
begin
item:= cola(ultimo);

ultimo := (ultimo mod N) + 1;


Num := Num - 1;
end SACAR;
function VER_TIEMPO return TIME is
begin
return cola(ultimo).tiempo_salida;
end VER_TIEMPO;
end almacen;
begin
null; -- inicializacion
end ALMACENES;

donde tenemos un conjunto de procesos P1 .. P8 y un conjunto de almacenes de proceso de 1 a 5.


Los procesos P1 y P2 son generadores de piezas. Estas se crean de forma cclica cada Tg1 y Tg2
respectivamente. Una vez se ha generado las piezas del proceso 1 pasan al almacn 1 donde tendrn que
permanecer durante un tiempo Tp1 seg. Lo mismo ocurre con las piezas de P2. Una vez han permanecido
el tiempo necesario en sus almacenes pasan a una zona comn que es el almacn 3 donde deben
permanecer Tp3 seg. Una vez han terminado esta fase las piezas que provienen del almacn 1 deben pasar
al almacn 4 durante Tp4 seg. Del mismo modo las piezas con origen en el almacn 2 debern pasar al
almacn 5 durante Tp5 seg. Los procesos P3,P4,P5,P6 se encargan de sacar las piezas de los almacenes y
pasarlos a otros una vez cumplido el tiempo de permanencia en los mismos .Finalmente los procesos P7 y
P8 se encargarn de sacarlos cumplido el tiempo.
Ejercicios.
1. Disear e implementar un programa en Ada que controle el sistema propuesto mostrando en
cada momento el estado de los almacenes ( numero de piezas que contiene ) y los tiempos
mnimos, mximos y medios de permanencia de las piezas en la planta.
2. Controlar los tiempos de permanencia de cada pieza en cada almacn, considerando que una
pieza ser defectuosa si sobrepasa el tiempo de cada zona en 2 segundos para la seccin de
barnizado, 4 la de secado y 6 la de cocido.
Restricciones.
Tg1=1 seg.
Tg2=2 seg.
Tamao almacn 1 : 10 piezas.
Tamao almacn 2 : 10 piezas.
Tamao almacn 3 : 15 piezas
Tamao almacn 4 : 12 piezas
Tamao almacn 5 : 12 piezas.
Tp1=3 seg.
Tp2=4 seg.
Tp3=10 seg.
Tp4=5 seg. Tp5=5 seg.
Propuesta: El programa principal podra tener entre otras posibles estas declaraciones (NOTA: faltara
implementar el cuerpo de las tareas)
WITH Ada.Float_Text_IO; use Ada.Float_Text_IO;
with ALMACENES;use ALMACENES;
with CALENDAR;use CALENDAR;
with BARRERAS;use BARRERAS;
procedure trabajo is

type BARNIZADO is array (integer range 1..2) of ALMACEN(N=>10);


type COCIDO is array (integer range 1..2) of ALMACEN(N=>12);
BARNIZ:Barnizado;
SECAD: ALMACEN(N=>15);
COCID:Cocido;
TYPE Position IS RECORD
Row
:integer:= 1;
Column:integer:= 1;
END RECORD;
entrada:barrera;
pant:pantalla;
task type generador(gid:
task type barn_seca(gid:
task type seca_coci(gid:
task type consumidor(gid:
-- cuerpo de las tareas
P1: GENERADOR(1,1,3);
P2: GENERADOR(2,2,4);
P3: BARN_SECA(1,3,15);
P4: BARN_SECA(2,4,15);
P5: SECA_COCI(1,5,5);
P6: SECA_COCI(2,6,5);
P7: CONSUMIDOR(1,7);
P8: CONSUMIDOR(2,8);

INTEGER; Tg:
INTEGER;pid:
INTEGER;pid:
INTEGER;pid:

begin
barniz(1).INICIALIZAR;
barniz(2).INICIALIZAR;
secad.INICIALIZAR;
cocid(1).INICIALIZAR;
cocid(2).INICIALIZAR;
pant.tomar;
entrada.abrir;
end trabajo;

Solucin 1.
task body GENERADOR is
i: INTEGER:=0;
P:PIEZA;
begin
entrada.entrar;
loop
i := i + 1;
delay duration(Tg);
P.numero:=i;
P.tipo:=gid;
P.tiempo_generacion:=clock;
P.Tiempo_salida:=clock;
barniz(gid).ANYADIR(P,Tp);
end loop
end generador;
task body BARN_SECA is
P:PIEZA;
begin
entrada.entrar;
loop
barniz(gid).NO_vacia;
delay until barniz(gid).VER_TIEMPO;
barniz(gid).SACAR(P);
secad.ANYADIR(P,tp);
secad.ESTADO_ALMACEN;
end loop;
end BARN_SECA;
task body SECA_COCI is
P:PIEZA;
begin

NATURAL;tp: NATURAL);
INTEGER;tp: NATURAL);
INTEGER;tp: NATURAL);
INTEGER);

entrada.entrar;
loop
secad.NO_vacia;
if secad.TIPO(gid) then
delay until secad.VER_TIEMPO;
secad.SACAR(P);
cocid(gid).ANYADIR(P,tp);
else
delay 1.0;
end if;
end loop;
end SECA_COCI;
task body CONSUMIDOR is
P:PIEZA;
Tiempo,T_max,T_min,T:duration;
Tm:float;
begin
entrada.entrar;
tiempo:=duration(0);
t_max:=duration(0);
t_min:=duration(100);
loop
cocid(gid).NO_VACIA;
delay until cocid(gid).VER_TIEMPO;
cocid(gid).sacar(P);
T:=clock-P.tiempo_generacion;
Tiempo:=Tiempo+T;
Tm:=float(Tiempo)/float(P.numero);
if T>t_max then t_max:=T;end if;
if T<t_min then t_min:=T;end if;
pant.tomar;
end loop;
end CONSUMIDOR;

Solucin 2.
task body GENERADOR is
i: INTEGER:=0;
P:PIEZA;
begin
entrada.entrar;
loop
i := i + 1;
delay duration(Tg);
P.numero:=i;
P.tipo:=gid;
P.tiempo_generacion:=clock;
P.Tiempo_salida:=clock;
barniz(gid).ANYADIR(P,Tp);
pant.tomar;
pos1.Row := 8*gid; pos1.column := 5;Goto_XY(pos1.column,pos1.row);
gnat.io.put("ANYADO: ");gnat.io.put(P.tipo);gnat.io.put("");gnat.io.put(P.numero);
barniz(gid).ESTADO_ALMACEN;
pant.dejar;
end loop;
end generador;
task body BARN_SECA is
P:PIEZA;
T:time;
begin
entrada.entrar;
loop
barniz(gid).NO_vacia;
delay until barniz(gid).VER_TIEMPO;
barniz(gid).SACAR(P);
T:=clock;
secad.ANYADIR(P,tp);

pant.tomar;
pos1.row:= 1;pos1.column:= 1;Goto_XY(pos1.column,pos1.row);
if T<barniz(gid).VER_TIEMPO+duration(1.0) then
gnat.io.put("Pieza ");gnat.io.put(P.tipo);gnat.io.put("");gnat.io.put(P.numero);
gnat.io.put(" Barnizado correcto. ");
else pos1.row:=2;Goto_XY(pos1.column,pos1.row);
gnat.io.put("Pieza ");gnat.io.put(P.tipo);gnat.io.put("");gnat.io.put(P.numero);
gnat.io.put(" Barnizado defectuoso.");
end if;
pos1.Row := 12; pos1.column := 35;Goto_XY(pos1.column,pos1.row);
gnat.io.put(P.tipo);gnat.io.put("-");gnat.io.put(P.numero);
secad.ESTADO_ALMACEN;
pant.dejar;
end loop;
end BARN_SECA;
task body SECA_COCI is
P:PIEZA;
T:time;
begin
entrada.entrar;
loop
secad.NO_vacia;
if secad.TIPO(gid) then
delay until secad.VER_TIEMPO;
secad.SACAR(P);
T:=clock;
cocid(gid).ANYADIR(P,tp);
pant.tomar;
pos1.row:= 3;pos1.column:= 30;Goto_XY(pos1.column,pos1.row);
if T<secad.VER_TIEMPO+duration(2.0) then
gnat.io.put("Pieza ");gnat.io.put(P.tipo);gnat.io.put("");gnat.io.put(P.numero);
gnat.io.put(" Secado correcto. ");
else pos1.row:=4;Goto_XY(pos1.column,pos1.row);
gnat.io.put("Pieza ");gnat.io.put(P.tipo);gnat.io.put("");gnat.io.put(P.numero);
gnat.io.put(" Secado defectuoso.");
end if;
pos1.Row := 8*gid; pos1.column :=
55;Goto_XY(pos1.column,pos1.row);
gnat.io.put(P.tipo);gnat.io.put("-");gnat.io.put(P.numero);
cocid(gid).ESTADO_ALMACEN;gnat.io.put(":CONSUMO");
pant.dejar;
else
delay 1.0;
end if;
end loop;
end SECA_COCI;
task body CONSUMIDOR is
P:PIEZA;
Tiempo,T_max,T_min,T:duration;
Tm:float;
TT:time;
begin
entrada.entrar;
tiempo:=duration(0);
t_max:=duration(0);
t_min:=duration(100);
loop
cocid(gid).NO_VACIA;
delay until cocid(gid).VER_TIEMPO;
cocid(gid).sacar(P);
TT:=clock;
T:=TT-P.tiempo_generacion;
Tiempo:=Tiempo+T;

Tm:=float(Tiempo)/float(P.numero);
if T>t_max then t_max:=T;end if;
if T<t_min then t_min:=T;end if;
pant.tomar;
pos1.row:=1;pos1.column:= 50;Goto_XY(pos1.column,pos1.row);
if TT<cocid(gid).VER_TIEMPO+duration(3.0) then
gnat.io.put("Pieza ");gnat.io.put(P.tipo);gnat.io.put("");gnat.io.put(P.numero);
gnat.io.put(" Cocido correcto. ");
else pos1.row:=2;Goto_XY(pos1.column,pos1.row);
gnat.io.put("Pieza ");gnat.io.put(P.tipo);gnat.io.put("");gnat.io.put(P.numero);
gnat.io.put(" Cocido defectuoso.");
end if;
pos1.row:=20;pos1.column:=5+38*(gid-1);Goto_XY(pos1.column,pos1.row);
gnat.io.put("Tiempo medio :");put(Tm,5,5,0);gnat.io.put(" segundos");
pos1.row:=21;pos1.column:=5+38*(gid-1);Goto_XY(pos1.column,pos1.row);
gnat.io.put("Tiempo maximo:");put(float(T_max),5,5,0);
gnat.io.put(" segundos");
pos1.row:=22;pos1.column:=5+38*(gid-1);Goto_XY(pos1.column,pos1.row);
gnat.io.put("Tiempo minimo:");put(float(T_min),5,5,0);
gnat.io.put(" segundos");
pant.dejar;
end loop;
end CONSUMIDOR;

Pregunta 5 (1.5 p): dado el siguiente conjunto de tareas definidas como T ? (C i , Pi , Di ) (cmputo,
periodo, deadline), determinar sin son planificables con el criterio de asignacin de prioridades Rate
Monotonic (Monotnico en frecuencia).
T1=(1,4,4); T2=(2,6,6); T3=(3,10,10);
?? Con el test de utilizacin de la CPU. Nota: U(3)=0.77
U=1/4+2/6+3/10=0.8>(3) . No planificable.
?? En caso de que el test anterior de un sistema no planificable, aplicar el test de tiempos de
finalizacin.

?? Supongamos que los datos varan en de la siguiente forma: T1=(1,4,2); T2=(2,6,3); T3=(3,10,4). Es
valido el anlisis anterior o se debera realizar ms clculos? No. Solo comparar el instante de
finalizacin con el plazo limite Por qu? Porque la ordenacin de prioridades se mantiene Cumplen
las tareas con sus restricciones temporales? No falla la tercera

Pregunta 6 (3.0 p): Sea un ro con un transbordador que lleva coches de la orilla norte a la sur y
viceversa. Puede llevar como mximo 10 coches en cada viaje. Se busca implementar una tarea en Ada
que mediante comunicacin por cita provea el servicio de transbordador comentado a las tareas coche que
realizan las siguientes llamadas sucesivas cada vez que desean pasar el ro:

iterar
Transbordador.Subir(orilla,aceptacion);--subir al transbordador
Sino se acepta esperar 4 segundos
Hasta aceptacin:
Transbordador.Bajar;--bajar cuando se llega a la orilla
Implementar el cdigo de la tarea transbordador y de las tareas coche que cumpla las siguientes
posibilidades:
?? El transbordador realiza un viaje cuando ha dejado subir a 10 coches en la orilla en la que se
encuentra
?? El transbordador realiza un viaje cuando ha recogido 10 coches o ha esperado ms de 10 segundos
en la orilla (pero no se permite hacer el viaje de vaco).
with Gnat.Io;
use Gnat.Io;
procedure Principal is
task Transbordador is
entry Pasar_Puente (
Direccion : in
Integer;
Arriba
:
out Boolean );
entry Bajar;
end Transbordador;
task body Transbordador is
Direc_Trans : Integer := 0;
Coches
: Integer := 0;
salir:boolean;
begin
loop
loop
salir:=false;
select
when (Coches<11)=>
accept Pasar_Puente (
Direccion :
Integer;
Arriba
:
out Boolean ) do
Arriba:=True;
if (Direccion=Direc_Trans) and Arriba then
Coches:=Coches+1;
end if;
Arriba:=False;
end Pasar_Puente;
or delay 10.0;
salir:=true;
end select;
exit when (Coches=10) or (salir and coches>0);
end loop;
loop
accept Bajar do
Coches:=Coches-1;
end Bajar;
exit when Coches=0;
end loop;
if Direc_Trans=1 then
Direc_Trans:=0;
else
Direc_Trans:=1;
end if;
end loop;
end Transbordador;
task type Coche (Dir_Coche:Integer);
task body Coche is
Aceptado : Boolean := False;
direccion:integer;
begin
direccion:=dir_coche;
loop
loop
Transbordador.Pasar_Puente(Direccion,Aceptado);

if not Aceptado then


delay 4.0;
end if;
exit when Aceptado;
end loop;
transbordador.bajar;
if Direccion=1 then Direccion:=0;
else Direccion:=1;
end if;
end loop;
end Coche;
begin
null;
end Principal;

Potrebbero piacerti anche