dr inż. Dariusz Pierzchała
Instytut Systemów Informatycznych
Symulacja
z
MODSIM II
Materiały szkoleniowe cz. III
Wyzwalacze, monitory zmiennych oraz procedury
zewnętrzne w języku MODSIM II
Wyzwalacz TriggerObj
• Konstrukcja obiektowa umożliwiająca synchronizację
aktywności:
– wstrzymanie metody TELL lub WAITFOR do
nieokreślonej z góry chwili;
– wznowienie wstrzymanych metod przez inną
metodę, np. po zmianie określonego warunku;
• Składnia:
WAIT FOR trigger object [ TO ] Fire
Sekwencja po poprawnym zwolnieniu
[ ON INTERRUPT
Sekwencja po przerwaniu przez InterruptTrigger ]
END WAIT;
Wyzwalacz TriggerObj
• Przykład:
landedSignal : TriggerObj;
...
IF flying
WAIT FOR landedSignal TO Fire
END WAIT;
END IF;
ASK airport TO assignRefueler (tankTruck);
WAIT FOR tankTruck TO refuel (SELF, fuelCapacity);
END WAIT;
Wyzwalacz TriggerObj
• Obiekt TriggerObj – wybrane składowe:
– ASK Method:
• Dump,
• InterruptTrigger,
• NumWaiting,
• Release;
– TELL Method
• Trigger;
– WAITFOR Method
• Fire;
Monitory
• Wynikiem działania programu symulacyjnego jest zazwyczaj
zbiór danych lub oszacowania opisujące pewne charakterystyki
systemu;
• Gromadzenie danych podczas eksperymentu (np. każdorazowo
po zmianie wartości pewnej zmiennej) wymaga
specjalizowanych mechanizmów;
• MODSIM II posiada wbudowane mechanizmy automatycznego
monitorowania i wyznaczania statystyk dla zmiennych typu:
– enumeryczne typy, INTEGER, REAL, STRING, BOOLEAN, typ
object, typ record oraz typ array;
• Monitory obsługują:
– zmienne (wyżej wymienionych typów),
– pola w obiektach,
– pola w rekordach,
– obiekty grupowe (np. kolejki, stosy itp.),
– obiekty – zasoby;
Monitory - deklaracja typu
< id > =MONITOR < type > OBJECT [(< id
0
>,...)]
< variable 0 > : < type 0 >;
...
ASK METHOD ...
...
TELL METHOD ...
...
LMONITOR METHOD ...
...
RMONITOR METHOD ...
...
END OBJECT;
< id > - nazwa typu obiektowego monitora
< type > - nazwa typu monitorowanego
< id
0
>
- nazwa przodka monitora
Monitory - deklaracja typu
Przykład
TYPE
monitorObj = MONITOR MyType OBJECT(someObj)
. . . pola i metody
LMONITOR METHOD leftMethod;
LMONITOR METHOD secondleftMethod;
RMONITOR METHOD rightMethod;
END OBJECT;
Monitory - definicja typu
OBJECT monitorObj;
LMONITOR METHOD leftMethod;
BEGIN
. . . {implementacja metody}
END METHOD;
. . . {implementacja pozostałych metod}
END OBJECT;
Sposób dołączenia monitora
• Zmienna lub pole obiektu (rekordu) dowolnego typu może zostać
zadeklarowana jako monitorowana;
• W deklaracji można podać typ monitora (opcjonalnie);
– Może być więcej niż jeden typ monitorujący dla jednej
zmiennej;
– Typy monitorujące wymienia się w liście po słowie „BY”;
VAR
waitingTime : LMONITORED REAL;
length : LMONITORED REAL BY RStatObj, RTimedStatObj;
• Typ obiektu monitora musi być zgodny z typem monitorowanej
zmiennej.
Monitorowanie typów danych
• Istnieje możliwość definiowana własnych, monitorowanych typów
danych:
TYPE
MyType = LMONITORED INTEGER [BY MyMonType];
VAR
myMonitoredVar1, myMonitoredVar2 : MyType;
Monitory - własności
• monitor może dziedziczyć z innych obiektów, przy czym
obiektem bazowym może być zarówno typ monitorowy lub
zwykły typ obiektowy;
• obiekt, który dziedziczy z obiektu będącego monitorem
musi być monitorem tego samego typu danych;
• tylko monitor może zawierać metody typu: LMONITOR i
RMONITOR;
• monitor może być statyczny lub dynamiczny;
• monitor może posiadać dowolną liczbę metod: left- i right-
hand;
• jeśli jest więcej niż jedna metoda określonego rodzaju,
wtedy są one wywoływane wg kolejności deklarowania;
Wbudowane procedury (funkcje)
• ADDMONITOR(IN v : any-variable; IN m : monitor-
object)
• ACTIVATE(IN v : any-variable; IN m : monitor-object)
• DEACTIVATE(IN v : any-variable; IN m : monitor-object)
• GETMONITOR(IN v : any-variable; IN m : monitor-name)
: monitor-object
• NEWVALUE
• UPDATEVALUE(IN x : any-type)
• VALUE
Monitory statyczne
TYPE
MonitorSample = MONITOR INTEGER OBJECT
LMONITOR METHOD SetNewValue;
RMONITOR METHOD GetOldValue;
END ONJECT;
OBJECT MonitorSample
LMONITOR METHOD SetNewValue;
BEGIN
OUTPUT(”SetNewValue to”, NEWVALUE);
END METHOD;
RMONITOR METHOD GetOldValue;
BEGIN
OUTPUT(”GetOldValue, which is”, VALUE);
END METHOD;
END OBJECT;
Monitory statyczne
VAR
queuelen : LRMONITORED INTEGER BY MonitorSample;
BEGIN
queuelen := 0;
queuelen := queuelen + 1;
END MODULE.
Monitory dynamiczne
VAR
monitoredVariable : LMONITORED MyType;
monitor, mon : monitorObj;
BEGIN
. . .
NEW(monitor);
ADDMONITOR(monitoredVariable, monitor);
. . .
OUTPUT(GETMONITOR(monitoredVariable, monitorObj).Mean);
. . .
DEACTIVATE(monitor);
. . .
REMOVEMONITOR(monitoredVariable, monitor);
DISPOSE(monitor);
END MODULE.
Monitory - typy wbudowane
• MODSIM dostarcza cztery podstawowe typy monitorów
statystycznych:
– zwykłe:
• IStatObj,
• RStatObj;
– ważone czasem:
• ITimedStatObj,
• RTimedStatObj;
• oraz sześć typów danych monitorowanych:
– SINTEGER = LMONITORED INTEGER BY IStatObj;
– TSINTEGER = LMONITORED INTEGER BY ITimedStatObj;
– BINTEGER = LMONITORED INTEGER BY IStatObj, ITimedStatObj;
– SREAL = LMONITORED REAL BY RStatObj;
– TSREAL = LMONITORED REAL BY RTimedStatObj;
– BREAL = LMONITORED REAL BY RStatObj, RTimedStatObj;
Monitory - statystyki
• Do wyznaczanych statystyk należą:
– Licznik (liczba obserwacji)
– Maksimum
– Minimum
– Suma
– Wartość średnia
– Suma kwadratów
– Średnia kwadratowa
– Wariancja
– Odchylenie standardowe
a także
– Histogram
Statystyki
• Średnia
• Średnia kwadratowa
Statystyki
• Wariancja
• Odchylenie kwadratowe
Statystyki ważone czasem
• Średnia
• Średnia kwadratowa
Statystyki ważone czasem
• Wariancja
• Odchylenie kwadratowe
Histogramy
• Histogramy są zbierane automatycznie jak i inne statystyki
(należy jednak najpierw ustawić pewne parametry):
ASK waitingTime TO SetHistogram ( low, high, interval );
• Odwoływanie się do histogramu jest identyczne jak do tablicy:
FOR i := 0 TO 21
OUTPUT ( waitingTime.GetHistogram[ i ] );
END FOR;
Przykład
MAIN MODULE test2;
FROM StatMod IMPORT RStatObj, histogram;
FROM RandMod IMPORT RandomObj;
VAR
y : LRMONITORED REAL BY RStatObj;
m : RStatObj;
h : histogram;
i : INTEGER;
r : RandomObj;
Przykład – c.d.
NEW(r);
m := GETMONITOR(y, RStatObj);
ASK m TO SetHistogram(0, 30, 3);
FOR i := 0 TO 1000
y := ASK r Normal(15.0, 5.0);
END FOR;
OUTPUT(”From ”, ASK m Minimum, ” -> ”, ASK mMaximum, ”,Sum”,
ASK m Sum);
OUTPUT(”Mean ”, ASK m Mean(), ”, mean square ”, ASK m
MeanSquare());
OUTPUT(”Variance ”, ASK m Variance(), ”, Standard deviation ”, ASK m
StdDev());
h :=ASK m GetHistogram();
OUTPUT(”Off low end ”, h[LOW(h)], ”, off high end ”, h[HIGH(h)]);
FOR i :=LOW(h) + 1 TO HIGH(h) - 1
OUTPUT(i, ”: ”, h[i]);
END FOR;
END MODULE.
Interfejs do języka C, C++
Zastosowanie
• MODSIM bazuje na języku, bibliotekach, kompilatorze i
linkerze języka C++;
• Możliwe jest dwukierunkowe przesyłanie komunikatów:
– z procedur MODSIM’a do procedur C++;
– i odwrotnie…;
• Wykorzystać można do rozszerzenia funkcjonalności
programu o np.:
• komunikację sieciową,
• dostęp do baz danych,
• obliczenia numeryczne,
• …;
Schemat zastosowania – po stronie
MODSIM’a
• Powołanie modułów wg zasady:
Dxxx.mod
- DEFINITION MODULE dla procedur;
Ixxx.mod
- IMPLEMENTATION MODULE dla
procedur
(często jest to tylko BEGIN i END
MODULE);
• Zadeklarowanie procedur w MODSIM’ie:
PROCEDURE ior(IN a, b:INTEGER):INTEGER; NONMODSIM;
lub
PROCEDURE ior(IN a, b:INTEGER):INTEGER; NONMODSIM”C”;
Schemat zastosowania – po stronie C++
• Powołanie modułów wg zasady:
xxx.cpp
- Moduł C++;
xxx.c
- Moduł C;
• Korzystanie ze specjalnych typów danych:
#include <modsim.h>
MODSIM
C++
C++ odpowiednik
BOOLEAN MS_BOOLEAN char
INTEGER
MS_INTEGER
long
REAL
MS_REAL
double
STRING
MS_STRING
char *
CHAR
MS_CHAR
unsigned char
enumeration
MS_ENUM
int
ARRAY
MS_ARRAY
char *
RECORD
MS_RECORD
MS_BaseRec
OBJECT
MS_OBJECT
MS_BaseObj
Schemat zastosowania – po stronie C++
• Procedury – przykład 1:
– parametry INOUT przekazywane są przez wskaźniki;
MODSIM
DEFINITION MODULE divrem;
PROCEDURE DIVREM(INOUT a, b: INTEGER); NONMODSIM;
END MODULE.
IMPLEMENTATION MODULE divrem;
END MODULE.
C++
#include <modsim.h>
void DIVREM ( MS_INTEGER *a, MS_INTEGER *b )
{
long ares, bres;
ares = (long) *a / (long) *b;
bres = (long) *a%(long) *b;
(MS_INTEGER) *a = ares;
(MS_INTEGER) *b = bres;
}
Schemat zastosowania – po stronie C++
• Procedury – przykład 2:
MODSIM
DEFINITION MODULE quad;
PROCEDURE Quadratic ( IN a, b, c: REAL;
OUT r1, r2: REAL): BOOLEAN; NONMODSIM;
END MODULE.
IMPLEMENTATION MODULE quad;
END MODULE.
C++
#include <modsim.h>
MS_BOOLEAN Quadratic(MS_REAL a, MS_REAL b, MS_REAL c, MS_REAL *r1,
MS_REAL *r2)
{
double disc, den;
disc = ((double) b * (double) b) - 4.0 * (double) a * (double) c;
if (disc < 0.0) return(MS FALSE);
den = 2.0 * (double) a;
(MS_REAL) *r1 = (- (double) b + sqrt(disc)) / den;
(MS_REAL) *r2 = (- (double) b - sqrt(disc)) / den;
return (MS_TRUE);
}
Schemat zastosowania – po stronie C++
• Procedury – przykład 3:
MODSIM
DEFINITION MODULE rle;
PROCEDURE SCOMPRESS(IN s:STRING; OUT res:STRING);
NONMODSIM;
END MODULE.
IMPLEMENTATION MODULE rle;
END MODULE.
Schemat zastosowania – po stronie C++
• Procedury – przykład 3:
C++
#include <stdlib.h>
#include <string.h>
#include <modsim.h>
void UtilMod RuntimeError(MS_STRING);
void SCOMPRESS(MS_STRING s, MS_STRING *res)
{
char *tmp, *ss, c; int cnt, o; register int i;
ss = (char *) s;
if ((tmp = (char *) malloc(2 * strlen(ss))) == NULL)
UtilMod RuntimeError(MS_CreateString((MS_CSTRING) ”no memory”));
i = 1; cnt = 1; c = ss[0]; o = 0;
loop: if (i >= strlen(ss))
{
tmp[o++] = cnt; tmp[o++] = c; tmp[o] = 0;
*res = MS CreateString((MS_CSTRING) tmp);
free(tmp);
return;
}
if (ss[i] == c) f i++; cnt++; g
else f tmp[o++] = cnt; tmp[o++] = c; cnt = 1; c = ss[i]; g
goto loop;
}