#define QLEN 5
mtype = {m1, m2, m3, const}
chan q = [QLEN] of {mtype, byte, mtype}
active proctype A() priority 10{
q!m1;
q!m2(20, const);
q!m3, 4, 0;
q!m2(5);
q!m3(4, const);
}
Afisand instructiunile executate(-p) si mesajele transmise (-s). Ce se intampla daca se transmit mesaje de dimensiune mai mica decat a canalului?
Nota: proceselor li se pot aloca si prioritati(un proces de prioritate 10 este executat de 10 ori mai des decat unul de prioritate 1).
active proctype B() priority 1{
do
:: q?m1
:: q?m2,_,_
od
}
si simulati. Ce se observa?active proctype C() priority 10{
byte var = 4;
byte var1;
do
:: q ? (m3,var1, const) ->
if
:: (var1 == var) -> break
:: else -> skip
fi
od
}
Simulati, afisand si variabilele locale (-l). Ce se intampla cu procesul C?
Q2: modificati codul procesului C, schimband ? cu ?? si rulati. Ce se observa?
q!m3, 4, 0;cu
q!m3, 2, const;, salvati intr-un nou fisier si simulati. Observati ca procesul C citeste ambele mesaje de tip m3 de pe canal. Acum schimbati linia
:: q ?? (m3,var1, const) ->din cadrul procesului C cu
:: q ?? (m3,eval(var), const) ->Ce se observa la simulare? A mai fost citit primul mesaj m3? Puteti vizualiza diferentele dintre cele doua fisiere (modele) rulate cu ajutorul comenzii
# sdiff fis1 fis2
chan q = [5] of {byte}
active proctype A(){
do
:: q!20
od
}
active proctype B(){
do
:: q?20
od
}
active proctype C(){
do
:: (len(q) == 3) ->
skip
:: full(q) ->
skip
:: nfull(q) ->
skip
:: empty(q) ->
skip
:: nempty(q) ->
skip
od
}
Urmariti executabilitatea instructiunilor din C pentru diferite nivele de umplere a buffer-ului canalului.
typedef name { decl_lst }
decl_lst: one_decl [ ';' one_decl ] *
one_decl: [ visible ] typename ivar [',' ivar ] *
ivar : name [ '[' const ']' ] [ '=' any_expr | '=' ch_init ]
Structurile de date pot contine alte structuri de date si pot fi transmise pe canale de date.
mtype = {m1, m2, m3};
typedef mesaj {
mtype tip;
byte c1;
byte c2;
};
chan q = [0] of {mesaj};
active proctype A(){
mesaj mt;
mt.tip=m1;
mt.c1=0;
mt.c2=5;
q!mt;
}
active proctype B(){
mesaj mt;
q?mt;
}
Rulati codul si comentati rezultatul.
#define alias (expr)sau chiar secvente de cod.
#define functie(arg1 [, argi] *) instr [; instr] *
#define copy(from, to) to.tip = from.tip; to.c1 = from.c1; to.c2 = from.c2;Integrati aceasta definitie in exemplul anterior si modificati codul procesului B pentru a copia datele receptionate intr-o alta variabila mesaj.
Pentru simplificarea modelului consideram cazul liftului care ajunge la un etaj anume si trebuie sa ia decizia daca este necesar sa deschida sau nu usile.
Un model simplificat al liftului este:
mtype = { sus, jos }
mtype directie;
chan q = [0] of {mtype};
active proctype lift(){
if
:: directie = sus; goto urcare;
:: directie = jos; goto coborare;
fi;
urcare:
// "Verifica" daca a ajuns la ultimul etaj - proces nedeterminist.
// Q: de ce?
if
:: directie = jos;
goto deschide
:: skip
fi;
if
:: q?sus; goto deschide
:: q?[jos] -> skip
fi;
coborare:
if
:: directie = sus;
goto deschide
:: skip
fi;
if
:: q?jos; goto deschide
:: q?[sus] -> skip
fi;
deschide:
skip;
if
:: (directie == sus) -> goto urcare
:: else -> goto coborare
fi;
end:
skip
}
active proctype panou(){
do
:: q ! sus
:: q ! jos
od
}