With Ada.Text_IO; Use Ada.Text_IO;
With Ada.Numerics.Discrete_Random;
With Ada.Numerics.Float_Random; Use Ada.Numerics.Float_Random;
With DeQue_G;
Procedure MMSC is
SIMULATION_PERIOD : constant Duration := 10.0;
MSGPROB : constant Float := 0.2;
N: constant Integer := 20;
Subtype Message is String(1..20);
Type MsIsdn is new Integer range 1..N;
Protected Screen is
Procedure Put_Line(S: String);
End Screen;
Protected type Flag(INITIAL_VALUE: Boolean := False) is
Procedure Set(V: Boolean := True);
Function Get return Boolean;
Private
VALUE : Boolean := INITIAL_VALUE;
End Flag;
FINISH : Flag;
Task type Subscriber is
Entry Init(NUMBER : MsIsdn );
Entry ReceiveMsg(FROM : MsIsdn ; MSG: Message);
End Subscriber;
Task MMSCenter is
Entry Send(FROM: MsIsdn; TO: MsIsdn; MSG: Message);
End MMSCenter;
Protected body Screen is
Procedure Put_Line(S: String) is
Begin
Ada.Text_IO.Put_Line(S);
End Put_Line;
End Screen;
Protected body Flag is
Procedure Set(V: Boolean:= True) is
Begin
VALUE := V;
End Set;
Function Get return Boolean is
Begin
Return VALUE;
End Get;
End Flag;
Function Flip(P: Float := 0.5) return Boolean is
G: Ada.Numerics.Float_Random.Generator;
Begin
ReSet(G);
Return (Random(G) '_');
G : MsIsdnRND.Generator;
Begin
SND(1..18):="Hello! I love you!";
ReSet(G);
Accept Init(NUMBER: MsIsdn) do
OWN := NUMBER;
End;
While not FINISH.Get loop
If Flip(MSGPROB) then
OTHER := Random(G);
MMSCenter.Send(OWN, OTHER, SND);
Screen.Put_Line(MsIsdn'Image(OWN) & " sent a message to "&
MsIsdn'Image(OTHER)&": "&SND);
End if;
Select
Accept ReceiveMsg(FROM: MsIsdn; MSG: Message) do
M := MSG;
F := FROM;
End;
Screen.Put_Line(MsIsdn'Image(OWN) & " got a message from "&
MsIsdn'Image(F)&": "&M);
Or
Delay 0.1;
End select;
End loop;
Loop
Select
Accept ReceiveMsg(FROM: MsIsdn; MSG: Message) do
M := MSG;
F := FROM;
End;
Screen.Put_Line(MsIsdn'Image(OWN) & " got a message from "&
MsIsdn'Image(F)&": "&M);
Or
Terminate;
End select;
End loop;
End SubScriber;
CUSTOMER_BASE : Array(MsIsdn) Of Subscriber;
Task body MMSCenter is
Type MsgData is record
SENDER : MsIsdn;
RECIPIENT : MsIsdn;
MSG : Message;
End record;
Package MsgQue is new DeQue_G(MsgData); Use MsgQue;
M : MsgData;
MESSAGES : DeQue;
Begin
While (not FINISH.Get) or else (Length(MESSAGES)>0) Loop
Select
Accept Send(FROM: MsIsdn; TO: MsIsdn; MSG: Message) do
HiExt(MESSAGES,MsgData'(FROM,TO,MSG));
End Send;
Screen.Put_Line("MMSC: Message received. Number of messages: "&
Integer'Image(Length(MESSAGES)));
Or
Delay 0.1;
End select;
If Length(MESSAGES) > 0 Then
M := LoV(MESSAGES);
Select
CUSTOMER_BASE(M.RECIPIENT).ReceiveMsg(M.SENDER,M.MSG);
LoRem(MESSAGES);
Screen.Put_Line("MMSC: Message delivered. Number of messages: "&
Integer'Image(Length(MESSAGES)));
Or
Delay 0.1;
End select;
End if;
End loop;
End MMSCenter;
Procedure Init is
Begin
For I in MsIsdn loop
CUSTOMER_BASE(I).Init(I);
End loop;
End Init;
Procedure Stop is
Begin
FINISH.Set;
End Stop;
Begin
Init;
Delay SIMULATION_PERIOD;
Stop;
End MMSC;
|