ˇ e vysok´e uˇcen´ı technick´e v Praze Cesk´ Fakulta elektrotechnick´a
ˇ VUT FEL katedra pocˇı´tacˇu˚ C
Bakal´aˇrsk´a pr´ace
Ud´ alostnˇ e orientovan´ y diskr´ etn´ı simulaˇ cn´ı syst´ em Jan Hadaˇs
Vedouc´ı pr´ace: doc. Ing. Jiˇr´ı Douˇsa, CSc
Studijn´ı program: Elektrotechnika a informatika strukturovan´ y bakal´aˇrsk´ y Obor: Informatika a v´ ypoˇcetn´ı technika ˇcerven 2007
ii
Podˇ ekov´ an´ı Dˇekuji panu Douˇsovi za veden´ı pr´ ace. iii
iv
Prohl´ aˇ sen´ı Prohlaˇsuji, ˇze jsem svou bakal´ aˇrskou pr´aci vypracoval samostatnˇe a pouˇzil jsem pouze podklady uveden´e v pˇriloˇzen´em seznamu. Nem´am z´ avaˇzn´ y d˚ uvod proti uˇzit´ı tohoto ˇskoln´ıho d´ıla ve smyslu §60 Z´akona ˇc. 121/2000 Sb., o pr´avu autorsk´em, o pr´ avech souvisej´ıc´ıch s pr´avem autorsk´ ym a o zmˇenˇe nˇekter´ ych z´akon˚ u (autorsk´ y z´ akon).
V Praze dne 10. 8. 2007
.............................................................
v
vi
Abstract The work is dealing with the design and implementation of a discrete simulation system oriented on events. The work contains an exemplary simulation in the implemented system.
Abstrakt Pr´ace se zab´ yv´ a n´ avrhem a implementac´ı diskr´etn´ıho simulaˇcn´ıho syst´emu orientovan´eho na ud´alosti. Souˇc´ ast´ı pr´ ace je uk´ azkov´ a simulace v implementovan´em simulaˇcn´ım syst´emu.
vii
viii
Obsah Seznam obr´ azk˚ u
xi
Seznam tabulek
xiii
´ 1 Uvod
1
2 Popis ˇ reˇ sen´ eho probl´ emu ´ 2.1 Uvod do problematiky simulaˇcn´ıch syst´em˚ u . . . . . . . . . 2.1.1 Simulace . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.2 Simulaˇcn´ı syst´emy . . . . . . . . . . . . . . . . . . . 2.2 Vymezen´ı c´ıl˚ u a popis struktury . . . . . . . . . . . . . . . 2.3 Reˇserˇsn´ı zpracov´ an´ı vzorov´eho simulaˇcn´ıho syst´emu SIMCP 2.3.1 Obecn´ y popis koncepce syst´emu . . . . . . . . . . . 2.3.2 Popis implementace . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
2 2 2 2 3 3 3 4
3 Anal´ yza a n´ avrh ˇ reˇ sen´ı 3.1 Obecn´ y popis koncepce syst´emu . . . . . . . 3.2 N´ avrh uˇzivatelsk´eho rozhran´ı . . . . . . . . 3.2.1 Pl´ anovac´ı pˇr´ıkazy . . . . . . . . . . . 3.2.2 Informaˇcn´ı metody . . . . . . . . . . 3.2.3 Pomocn´e funkce . . . . . . . . . . . 3.3 N´ avrh datov´ ych struktur . . . . . . . . . . . 3.3.1 Podrobn´ y rozbor navrˇzen´e struktury 3.3.2 Pomocn´e datov´e struktury . . . . . . 3.4 Volba implementaˇcn´ıho prostˇred´ı . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
6 6 6 6 7 7 8 8 8 9
. . . . . . . . . .
10 10 10 11 13 13 13 15 15 15 16
. . . . . . . . . .
17 17 17 17 19 21 23 23 23 25 25
4 Realizace 4.1 Knihovna simulation . . . . . . . . . . . . . 4.1.1 Implementace prioritn´ı fronty . . . . 4.1.2 Implementace seznamu ud´alost´ı . . . 4.1.3 Implementace ud´ alost´ı . . . . . . . . 4.1.4 Implementace uˇzivatelsk´eho rozhran´ı 4.1.4.1 Pl´ anovac´ı pˇr´ıkazy . . . . . 4.1.4.2 Informaˇcn´ı metody . . . . . 4.1.4.3 Pomocn´e funkce . . . . . . 4.1.5 Implementace obsluˇzn´eho rozhran´ı . 4.2 J´ adro syst´emu . . . . . . . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . . .
. . . . . . . . .
. . . . . . . . . .
. . . . . . . . .
. . . . . . . . . .
. . . . . . . . .
. . . . . . . . . .
. . . . . . . . .
. . . . . . . . . .
. . . . . . . . .
. . . . . . . . . .
5 Testov´ an´ı 5.1 Simulace vyt´ıˇzenosti l´ekaˇr˚ u . . . . . . . . . . . . . . . 5.1.1 Realizace modelu . . . . . . . . . . . . . . . . . 5.1.1.1 Implementace datov´ ych struktur . . . 5.1.1.2 Implementace ud´alost´ı . . . . . . . . . 5.1.2 Testov´ an´ı modelu . . . . . . . . . . . . . . . . . ˇ 5.2 C´ıslicov´ y obvod na u ´rovni hradel . . . . . . . . . . . . 5.2.1 Realizace modelu . . . . . . . . . . . . . . . . . 5.2.1.1 Implementace vstupn´ıch sign´al˚ u . . . 5.2.1.2 Implementace logick´ ych ˇclen˚ u. . . . . 5.2.1.3 Implementace speci´aln´ıch ud´alost´ı run ix
. . . . . . . . .
. . . . . . . . . .
. . . . . . . . . a
. . . . . . . . .
. . . . . . . . . .
. . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . terminate
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
6 Z´ avˇ er
27
7 Literatura
29
A Uˇ zivatelsk´ a pˇ r´ıruˇ cka A.1 Uˇzivatelsk´e rozhran´ı . . . A.1.1 Pl´ anovac´ı pˇr´ıkazy . A.1.2 Informaˇcn´ı metody A.1.3 Pomocn´e funkce . A.2 Instalace . . . . . . . . . .
31 31 31 32 32 33
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
B Obsah pˇ riloˇ zen´ eho CD
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
35
x
Seznam obr´ azk˚ u 5.1 5.2 5.3
Graf sloˇzitosti modelu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Schema ˇc´ıslicov´eho obvodu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Pr˚ ubˇehy vstupn´ıch sign´ al˚ u. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xi
21 23 24
xii
Seznam tabulek
xiii
xiv
´ KAPITOLA 1. UVOD
1
´ 1 Uvod Pˇri sv´em studiu na Elektrofakultˇe jsem se zaj´ımal o objektovˇe orientovan´e programov´an´ı. Bavilo mˇe vyv´ıjet aplikace, kter´e vyuˇz´ıvaj´ı propracovan´e datov´e struktury. Jako pˇr´ıklad uvedu semestr´aln´ı pr´ ace pro pˇredmˇety PJP a TJC. V semestr´aln´ı pr´aci pro PJP jsem programoval matematick´ y interpret, kter´ y pˇrekl´ ad´a do vnitˇrn´ı formy abstraktn´ıho syntaktick´eho stromu. Zad´an´ım pr´ ace z pˇredmˇetu TJC bylo napsat jednoduchou datab´azi. Obˇe aplikace jsem psal v jazyce C++, stejnˇe jako ˇradu prac´ı z jin´ ych pˇredmˇet˚ u. Tyto zkuˇsenosti jsem chtˇel z˚ uroˇcit ve sv´e bakal´aˇrsk´e pr´aci, proto jsem se rozhodl pro pr´aci implementaˇcn´ı se zamˇeˇren´ım na objektov´e programov´an´ı v jazyce C++. Na druhou stranu jsem se vˇsak chtˇel vyhnout pouˇzit´ı grafick´eho rozhran´ı, protoˇze tvorba grafick´eho rozhran´ı vyˇzaduje podrobnou znalost grafick´ ych funkc´ı nebo objektov´e knihovny, v obou pˇr´ıpadech z´avisl´ ych na dan´em operaˇcn´ım syst´emu. M´ ym c´ılem bylo naopak napsat k´od, kter´ y lze pˇreloˇzit v libovoln´em prostˇred´ı. Naj´ıt zad´ an´ı, kter´e by vyhovovalo tˇemto n´aroˇcn´ ym poˇzadavk˚ um nebylo jednoduch´e. Pˇri prohl´ıˇzen´ı vypsan´ ych t´emat jsem nach´azel pouze pr´ace charakteru hardwarov´eho, nebo pr´ ace zadan´e. Aˇz t´ema ”Diskr´etn´ı simulaˇcn´ı syst´em orientovan´ y na ud´alosti” plnˇe uspokojilo m´e poˇzadavky. Z tohoto pohledu mi zadan´e t´ema zcela vyhovovalo.
ˇ SEN ˇ EHO ´ ´ KAPITOLA 2. POPIS RE PROBLEMU
2
2 Popis ˇ reˇ sen´ eho probl´ emu 2.1 2.1.1
´ Uvod do problematiky simulaˇ cn´ıch syst´ em˚ u Simulace
´ celem simulac´ı je lepˇs´ı pochopen´ı zkouman´ Uˇ ych objekt˚ u. Simulace1 procesu z re´ aln´eho svˇeta zahrnuje pops´an´ı zkouman´eho procesu, vytvoˇren´ı simulaˇcn´ıho programu a n´ asledn´e experimentov´an´ı s modelem (prov´adˇen´ı simulaˇcn´ıho programu). Simulaˇcn´ı model2 se popisuje pomoc´ı jeho vlastnost´ı – atribut˚ u. D´ale je definov´an modelov´ y ˇcas (naz´ yv´an t´eˇz jako servisn´ı nebo simulaˇcn´ı ˇcas). Okamˇzit´a hodnota modelov´eho ˇcasu ˇr´ık´a, v jak´e f´azi simulace se model pr´ avˇe nach´ az´ı. Chov´an´ı modelu popisuj´ı soubory pravidel, kter´e ˇr´ıkaj´ı, jak se maj´ı jednotliv´e atributy mˇenit v z´avislosti na modelov´em ˇcase. Tyto popisy se naz´ yvaj´ı procesy. Procesy mohou b´ yt diskr´etn´ı nebo spojit´e: • Spojit´ y proces modeluje objekt, jehoˇz atributy se mˇen´ı spojitˇe. Popisuje se pomoc´ı soustavy matematick´ ych rovnic. Pˇr´ıkladem spojit´eho procesu je p´erov´an´ı u automobilu. • Diskr´etn´ı proces lze rozdˇelit na posloupnost ud´alost´ı. Ud´alost je zmˇena atributu, kter´a nast´av´a pro diskr´etn´ı hodnotu modelov´eho ˇcasu. Tyto ˇc´asti procesu jsou atomick´e – to znamen´a ˇze probˇehnou bez pˇreruˇsen´ı. Podrobnˇe se simulacemi zab´ yv´ a[2]. 2.1.2
Simulaˇ cn´ı syst´ emy
Simulaˇcn´ı syst´emy3 mohou b´ yt spojit´e nebo diskr´etn´ı. Spojit´e syst´emy se zab´ yvaj´ı simulac´ı jedin´eho spojit´eho procesu, diskr´etn´ı syst´emy umoˇzn ˇuj´ı simulaci v´ıce diskr´etn´ıch proces˚ u. Nejˇcastˇejˇs´ı aplikac´ı diskr´etn´ıho simulaˇcn´ıho syst´emu je syst´em hromadn´e obsluhy(d´ale SHO). SHO je syst´em kter´ y obsluhuje pˇr´ıchoz´ı poˇzadavky. Pokud syst´em nen´ı schopen poskytnout okamˇzitou obsluhu, ˇrad´ı poˇzadavky do fronty. Obslouˇzen´e poˇzadavky odch´az´ı ze syst´emu. Pˇr´ıkladem SHO je pedagogick´e oddˇelen´ı nebo tˇreba menza. D´ale se budu zab´ yvat jen diskr´etn´ımi syst´emy. Ty se dˇel´ı podle orientace na procesy nebo ud´alosti Syst´ em orientovan´ y na procesy popisuje simulaˇcn´ı model pomoc´ı proces˚ u. Proces obsahuje konkr´etn´ı ud´ alosti, tedy popisuje zmˇeny modelu nebo jeho ˇc´ast´ı. Typick´ ym pˇr´ıkladem 4 procesu je popis chov´ an´ı kan´ alu obsluhy . Pokud probˇehnou vˇsechny ud´alosti pl´anovan´e pro urˇcitou hodnotu modelov´eho ˇcasu, proces se pˇreruˇs´ı. Syst´ em orientovan´ y na ud´ alosti popisuje model pomoc´ı ud´alost´ı. Ud´alost je urˇcit´a atomick´a ˇc´ast jednoho nebo i v´ıce proces˚ u, kter´a probˇehne pro urˇcitou hodnotu modelov´eho ˇcasu bez pˇreruˇsen´ı. Typickou ud´ alost´ı je pˇr´ıchod poˇzadavku5 do syst´emu nebo uveden´ı kan´alu obsluhy v ˇcinnost. Podrobnˇeji se simulaˇcn´ımi syst´emy zab´ yv´a[2].
1
Simulace je ˇcinnost, kter´ a slouˇz´ı k z´ısk´ an´ı informac´ı o re´ aln´em syst´emu pomoc´ı simulaˇcn´ıho modelu. Simulaˇcn´ı model je napodobenina urˇcit´eho re´ aln´eho syst´emu, kter´ a slouˇz´ı k simulaci. 3 Vhodn´ y simulaˇcn´ı jazyk nebo soubor podprogram˚ u, kter´ y m´ a uˇzivateli usnadnit vytvoˇren´ı simulace. 4 Kan´ al obsluhy je prostˇredek, kter´ y poskytuje urˇcitou formu obsluhy. 5 Poˇzadavek je ˇza ´dost o urˇcitou formu obsluhy. 2
ˇ SEN ˇ EHO ´ ´ KAPITOLA 2. POPIS RE PROBLEMU
2.2
3
Vymezen´ı c´ıl˚ u a popis struktury
C´ılem moj´ı pr´ ace bylo implementovat simulaˇcn´ı syst´em orientovan´ y na ud´alosti. Syst´em m´ a poskytovat stejn´e uˇzivatelsk´e rozhran´ı jako poskytnut´ y vzorov´ y simulaˇcn´ı syst´em SIMCP[1], s pˇrihl´ednut´ım na odliˇsnosti dan´e orientac´ı na ud´alosti. Poˇzadavkem bylo tak´e pouˇzit´ı odliˇsn´ ych, pokud moˇzno efektivnˇejˇs´ıch datov´ ych struktur, neˇz pouˇz´ıv´a SIMCP. C´ıl pr´ace bych dekomponoval na nˇekolik d´ılˇc´ıch c´ıl˚ u: 1. N´avrh vhodn´eho uˇzivatelsk´e rozhran´ı. Rozhran´ı mus´ı zohledˇ novat orientaci na ud´alosti, ale z´aroveˇ n mus´ı zachovat maxim´ aln´ı kompatibilitu se syst´emem SIMCP. 2. N´avrh datov´ ych struktur. Jedn´ a se zejm´ena o seznam ud´alost´ı. Seznam ud´alost´ı mus´ı b´ yt setˇr´ıdˇen´ y podle modelov´eho ˇcasu, mus´ı se umˇet dynamicky prodluˇzovat a mus´ı m´ıt implementovan´e metody, kter´e budou podporovat pl´ anov´an´ı ud´alost´ı. 3. Implementace koneˇcn´eho n´ avrhu v jazyce C++. C´ılem je vytvoˇrit pˇrehledn´ y zdrojov´ y k´od, v´ ysledn´ y program mus´ı b´ yt stabiln´ı a efektivn´ı. 4. Ovˇeˇren´ı funkˇcnosti implementace. Fukˇcnost svoj´ı implementace ovˇeˇr´ım tak, ˇze v syst´emu vytvoˇr´ım simulaci vybran´eho SHO. Na prvn´ı dva podc´ıle se zamˇeˇr´ım v kapitole 3, implementaci podrobnˇe rozeberu v kapitole 4, podc´ıl 4 pak v kapitole 5.
2.3 2.3.1
Reˇ serˇ sn´ı zpracov´ an´ı vzorov´ eho simulaˇ cn´ıho syst´ emu SIMCP Obecn´ y popis koncepce syst´ emu
SIMCP je simulaˇcn´ı syst´em orientovan´ y na procesy. J´adrem syst´emu je seznam ud´alost´ı, kter´ y obsahuje z´ aznamy o procesech. Procesy se mohou nach´azet ve stavu aktivn´ı, potlaˇcen´ y, pasivn´ı nebo ukonˇcen´ y. Aktivn´ı proces je proces, kter´ y se pr´avˇe prov´ad´ı. Z´aznam tohoto procesu je v seznamu ud´alost´ı zaps´ an jako prvn´ı. Potlaˇ cen´ y proces je kaˇzd´ y proces napl´anovan´ y v seznamu ud´alost´ı kromˇe procesu, kter´ y je pr´avˇe aktivn´ı. Pasivn´ı proces je proces, kter´ y nen´ı napl´anovan´ y v seznamu ud´alost´ı ani ukonˇcen´ y. Ukonˇ cen´ y proces je proces, kter´ y se bˇehem sv´eho prov´adˇen´ı ukonˇcil. Takov´ y proces jiˇz nelze znovu napl´ anovat. K pl´anov´ an´ı proces˚ u slouˇz´ı metody: • Activate a Reactivate • Hold • Passivate • Wait • Cancel
ˇ SEN ˇ EHO ´ ´ KAPITOLA 2. POPIS RE PROBLEMU
4
Metoda Activate slouˇz´ı k pl´ anov´ an´ı pasivn´ıch proces˚ u. Metoda Reactivate slouˇz´ı k pˇrepl´ anov´ an´ı aktivn´ıch a potlaˇcen´ ych proces˚ u nebo k pl´anov´an´ı pasivn´ıch proces˚ u. Zavol´an´ı metody Activate na aktivn´ı nebo potlaˇcen´ y proces se projev´ı jako pr´azdn´ y pˇr´ıkaz. Procesy je moˇzn´e pl´ anovat na hodnotu modelov´eho ˇcasu kter´a je vˇetˇs´ı nebo rovna aktu´aln´ımu modelov´emu ˇcasu. Je implementov´ ano prioritn´ı pl´anov´an´ı, kter´e proces napl´anuje pro urˇcitou hodnotu modelov´eho ˇcasu jako prvn´ı, tedy pˇred vˇsechny jiˇz napl´anovan´e procesy a bezprostˇredn´ı pl´anov´an´ı, kter´e zp˚ usob´ı napl´ anov´ an´ı procesu pˇred aktivn´ı proces. Je li pouˇzito bezprostˇredn´ı pl´anov´an´ı, aktivn´ı proces se pˇreruˇs´ı a ˇr´ızen´ı se pˇred´a procesu, kter´ y byl napl´anov´an pˇred nˇej. Metodu Hold lze volat pouze na aktivn´ı proces. Zp˚ usob´ı pˇreruˇsen´ı procesu a jeho pˇrepl´anov´an´ı za dobu t(parametr metody hold). Vol´an´ım tohoto pˇr´ıkazu proces pˇrejde do stavu potlaˇcen´ y. Metodu Passivate lze volat pouze na aktivn´ı proces. Zp˚ usob´ı pˇreruˇsen´ı procesu a smaz´an´ı jeho z´aznamu ze seznamu ud´ alost´ı. Vol´an´ım tohoto pˇr´ıkazu proces pˇrejde do stavu pasivn´ı. Metoda Wait zp˚ usob´ı, ˇze pr´ avˇe aktivn´ı pˇr´ıkaz pˇrejde do stavu pasivn´ı a zaˇrad´ı se na konec fronty F(parametr metody Wait). Vol´an´ım tohoto pˇr´ıkazu proces pˇrejde do stavu pasivn´ı. Metoda Cancel volan´ a na aktivn´ı proces zp˚ usob´ı pˇreruˇsen´ı procesu a smaz´an´ı jeho z´aznamu ze seznamu ud´ alost´ı. Je li zavol´ ana na potlaˇcen´ y proces, odstran´ı pouze jeho z´aznam ze seznamu ud´ alost´ı. Vol´ an´ım tohoto pˇr´ıkazu proces pˇrejde do stavu pasivn´ı. 2.3.2
Popis implementace
Syst´em SIMCP je implementov´ an v knihovn´ach Simset a Simulation. Knihovna Simset definuje pomoc´ı tˇr´ıd CLink a CHead obousmˇernˇe sv´azan´ y seznam6 . Uˇzivatel 7 m˚ uˇze pomoc´ı dˇedˇen´ı vyuˇz´ıvat vlastnost´ı t´eto pˇreddefinovan´e datov´e struktury. CLink obsahuje definici elementu seznamu8 . Kaˇzd´ y element obsahuje kromˇe ukazatele na pˇrech˚ udce a n´ asledn´ıka tak´e ukazatel na hlavu seznamu9 . K dispozici jsou metody pro proch´ azen´ı seznamu, konkr´etnˇe metody vrat’ pˇredch˚ udce/n´asledn´ıka tohoto elementu, d´ ale metody pro vloˇzen´ı elementu na konec seznamu, nebo pˇred/za referenˇcn´ı prvek10 a metoda pro odstranˇen´ı prvku ze seznamu. CHead popisuje hlavu seznamu. Hlava seznamu dˇed´ı vlastnosti elementu, a nav´ıc upravuje celkovou strukturu seznamu do kruhu (topologie sbˇernice). To znamen´a ˇze nasledn´ık hlavy je prvn´ı prvek seznamu a pˇredch˚ udce hlavy je posledn´ı prvek seznamu. Hlava obsahuje nav´ıc metody pro z´ısk´an´ı prvn´ıho a posledn´ıho elementu, metodu pro smaz´ an´ı cel´eho seznamu a pomocn´e metody pro z´ısk´an´ı informac´ı o seznamu, konkr´etnˇe zda je seznam pr´ azdn´ y a kolik obsahuje prvk˚ u.
6
Typ seznamu, kdy kaˇzd´ y element obsahuje ukazatel na sv´eho pˇredch˚ udce i n´ asledn´ıka, takˇze je moˇzn´e seznam proch´ azet obˇema smˇery. 7 Dˇedˇen´ı – princip vyuˇz´ıvan´ y v obˇektovˇe orientovan´em programov´ an´ı. Dˇed´ıc´ı objekt – potomek obsahuje vˇsechny vlastnosti sv´eho pˇredka. 8 V n´ asleduj´ıc´ım textu pouˇz´ıv´ am term´ıny element a prvek seznamu jako synonyma. 9 Hlava seznamu je datov´ a struktura, kter´ a obsahuje glob´ aln´ı informace o seznamu, napˇr ukazatel na prvn´ı a posledn´ı prvek seznamu. 10 Prvek kter´ y slouˇz´ı k pˇresn´emu urˇcen´ı m´ısta v senamu ud´ alost´ı.
ˇ SEN ˇ EHO ´ ´ KAPITOLA 2. POPIS RE PROBLEMU
5
Knihovna Simulation obsahuje tˇr´ıdy CThread, CEventNotice a CProces. CThread implementuje pomocn´e fukce pro pr´aci s vl´akny11 v prostˇred´ı windows. Obsahuje status vl´ akna – informaci zda je vl´akno spuˇstˇen´e, pˇreruˇsen´e nebo ukonˇcen´e, d´ ale identifikaci vl´ akna12 a handle vl´akna13 . Vl´akno se inicializuje metodou InitThread, kter´ a zp˚ usob´ı vytvoˇren´ı nov´eho vl´akna a spr´avn´e nastaven´ı datov´ ych ˇclen˚ u tˇr´ıdy CThread. Obsahem novˇe vytvoˇren´eho vl´akna je metoda Start, zde implementovan´ a jako abstraktn´ı14 . Tˇr´ıda d´ale obsahuje metody pro spuˇstˇen´ı a zastaven´ı vl´akna. Tˇechto vlastnost´ı d´ ale vyuˇz´ıv´a tˇr´ıda CProces. Tˇ r´ıda CEventNotice implementuje element seznamu ud´alost´ı (naz´ yv´an t´eˇz z´aznam o procesu). Dˇed´ı vlastnosti tˇr´ıdy CLink a d´ale obsahuje ukazatel na proces (implementovan´ y v tˇr´ıdˇe CProces) a hodnotu modelov´eho ˇcasu, na kter´ y je proces napl´anovan´ y. Implementovan´ a je metoda pro zaˇrazen´ı prvku do seznamu. Tˇ r´ıda CProces dˇed´ı vlastnosti tˇr´ıd CThread a CLink. Obsahuje metody pro pl´anov´ an´ı proces˚ u, informaˇcn´ı metody a pomocn´e funkce. Obsah procesu definuje uˇzivatel v metodˇe Run v potomc´ıch t´eto tˇr´ıdy, proto je metoda Run implementov´ ana jako abstraktn´ı. Vytvoˇren´ı instance15 potomka t´eto tˇr´ıdy zp˚ usob´ı, ˇze se vytvoˇr´ı nov´e pozastaven´e vl´akno. Toto vl´akno je d´ıky vlastnostem dˇedˇen´ ym z CThread moˇzn´e pˇreruˇsit nebo obnovit(spustit). Obsahem vl´akna je metoda Start, kter´ a na zaˇc´ atku vol´a metodu Run. D´ıky vlastnostem z´ıskan´ ym ze tˇr´ıdy CLink je moˇzn´e vytvoˇrit z instanc´ı tˇr´ıdy CProces obousmˇernˇe sv´ azan´ y seznam, napˇr frontu pasivn´ıch proces˚ u. Tˇr´ıda obsahuje ukazatel na z´aznam v seznamu ud´alost´ı, ukazatel na hlavu seznamu ud´ alost´ı a informaci zda je proces ukonˇcen´ y. Informaˇ cn´ı metody slouˇz´ı k z´ısk´av´an´ı informac´ı o procesu. Jsou to metody Idle, EvTime, Terminated a NextEv. Idle vrac´ı true, pokud je proces pasivn´ı nebo ukonˇcen´ y. EvTime vrac´ı ˇcas, na kter´ y je proces napl´anov´an. Pokud napl´anov´an nen´ı, vrac´ı hodnotu -1. Terminated vrac´ı true, pokud je proces ukonˇcen. NextEv vrac´ı ukazatel na n´asleduj´ıc´ı proces v seznamu proces˚ u(vlastnost dˇedˇen´ a z CLink). Pokud proces nen´ı zaˇrazen do seznamu proces˚ u, metoda vrac´ı NULL. Pomocn´ e metody jsou Current a Time. Current vrac´ı ukazatel na aktivn´ı proces. Time vrac´ı aktu´ aln´ı hodnotu simulaˇcn´ıho ˇcasu.
11
Vl´ akno je ˇca ´st programu, kter´ a m˚ uˇze b´ yt spuˇstˇena nez´ avisle na ostatn´ıch ˇca ´stech. Unik´ atn´ı ˇc´ıslo, kter´e jednoznaˇcnˇe identifikuje vl´ akno. 13 Handle je identifikace datov´e struktury operaˇcn´ıho syst´emu(kernel objectu) v r´ amci jednoho procesu. Zde je pouˇzit pro pr´ aci s vl´ akny. 14 Je li metoda deklarov´ ana jako abstraktn´ı, znamen´ a to ˇze metoda nem´ a v dan´e tˇr´ıdˇe definici a bude definov´ ana aˇz v dˇed´ıc´ı tˇr´ıdˇe. 15 Instance je konkr´etn´ı objekt vytvoˇren´ y z dan´e tˇr´ıdy. 12
´ ´ ˇ SEN ˇ ´I KAPITOLA 3. ANALYZA A NAVRH RE
6
3 Anal´ yza a n´ avrh ˇ reˇ sen´ı 3.1
Obecn´ y popis koncepce syst´ emu
Simulaˇcn´ı syst´em bude popisovat model pomoc´ı ud´alost´ı. Bude obsahovat seznam ud´alost´ı a obsluˇzn´e j´adro, kter´e odeb´ır´ a a zpracov´ av´a ud´alosti napl´anovan´e v seznamu. Ud´alost se m˚ uˇze nach´azet ve stavu aktivn´ı, potlaˇcen´ a a pasivn´ı. Aktivn´ı je ud´ alost, kter´ a se pr´ avˇe prov´ ad´ı. Potlaˇ cen´ a je ud´ alost, kter´ a je napl´ anovan´a v seznamu ud´alost´ı. Pasivn´ı je ud´alost, kter´ a v seznamu ud´ alost´ı nen´ı napl´anovan´a. Ud´alosti jsou v seznamu ud´ alost´ı setˇr´ıdˇen´e podle hodnoty modelov´eho ˇcasu, na kterou jsou napl´anovan´e. Syst´em vˇzdy vyjme ze seznamu ud´alost, kter´a je prvn´ı na ˇradˇe a spust´ı ji. Aktivn´ı ud´alost m˚ uˇze pomoc´ı pl´ anovac´ıch pˇr´ıkaz˚ u pl´anovat dalˇs´ı ud´alosti. V okamˇziku, kdy tato ud´alost skonˇc´ı, syst´em vyjme a spust´ı dalˇs´ı ud´ alost. V syst´emu nebudou implementov´ any pl´ anovac´ı pˇr´ıkazy Hold, Wait a Passivate, protoˇze slouˇz´ı k pˇreruˇsen´ı procesu. Ze stejn´eho d˚ uvodu nebude implementov´ano ani bezprostˇredn´ı pl´anov´an´ı, to znamen´a ˇze ˇz´ adn´ a ud´ alost nem˚ uˇze b´ yt napl´anov´ana pˇred aktivn´ı ud´alost. To je zaruˇceno t´ım, ˇze se aktivn´ı ud´ alost nenach´ az´ı v seznamu ud´alost´ı.
3.2
N´ avrh uˇ zivatelsk´ eho rozhran´ı
Z d˚ uvodu zachov´ an´ı maxim´ aln´ı zpˇetn´e kompatibility se vzorov´ ym syst´emem SIMCP se budu snaˇzit zachovat stejnou strukturu uˇzivatelsk´eho rozhran´ı simulaˇcn´ıho syst´emu (d´ale jen rozhran´ı). Rozhran´ı mus´ı obsahovat pˇr´ıkazy pro pl´anov´an´ı ud´alost´ı, informaˇcn´ı metody, kter´e budou poskytovat informace o jednotliv´ ych ud´alostech a pomocn´e funkce. 3.2.1
Pl´ anovac´ı pˇ r´ıkazy
Pl´anovac´ı pˇr´ıkazy slouˇz´ı k napl´ anov´ an´ı ud´alosti do seznamu ud´alost´ı. Ud´alosti pl´anovan´e pro stejnou hodnotu modelov´eho ˇcasu jsou ˇrazeny do fronty1 . K napl´anov´an´ı ud´alost´ı budou implementov´any pˇr´ıkazy Activate a Reactivate, ke zruˇsen´ı jiˇz napl´anovan´e ud´alosti pˇr´ıkaz Cancel. Activate zp˚ usob´ı napl´ anov´ an´ı ud´ alosti na konkr´etn´ı hodnotu modelov´eho ˇcasu. Je li pˇr´ıkaz u ´spˇeˇsn´ y, vrac´ı hodnotu true. Pokud jiˇz je ud´alost napl´anovan´a, tak je pˇr´ıkaz ne´ uspˇeˇsn´ y, to znamen´ a ˇze se pl´ anov´ an´ı neprovede a pˇr´ıkaz vr´at´ı hodnotu false. Reactivate zp˚ usob´ı pˇrepl´ anov´ an´ı jiˇz napl´anovan´e ud´alosti, to znamen´a ˇze ud´alost bude smaz´ana ze seznamu ud´ alost´ı a napl´ anov´an na novou hodnotu modelov´eho ˇcasu. V pˇr´ıpadˇe ˇze ud´alost nen´ı napl´ anovan´ a v seznamu ud´alost´ı, Reactivate se projev´ı jako pˇr´ıkaz Activate. Je li pˇr´ıkaz u ´spˇeˇsn´ y, vrac´ı hodnotu true, v pˇr´ıpadˇe ne´ uspˇechu vrac´ı false. Specifikace um´ıstˇen´ı v seznamu ud´ alost´ı bude moˇzn´a n´asleduj´ıc´ımi zp˚ usoby: Pˇ r´ıkazy s frontovou discipl´ınou. Tyto pˇr´ıkazy napl´anuj´ı ud´alost za vˇsechny ud´alosti, kter´e jiˇz pro tuto hodnotu modelov´eho ˇcasu byly napl´anov´any. Jsou to pˇr´ıkazy Activate, ActivateAt a ActivateDelay. Pˇ r´ıkaz Activate bez parametr˚ u zp˚ usob´ı napl´anov´an´ı ud´alosti na aktu´aln´ı hodnotu modelov´eho ˇcasu. 1
Fronta je datov´ a struktura, typu FIFO, to znamen´ a ˇze prvek vloˇzen´ y jako prvn´ı bude vybr´ an jako prvn´ı.
´ ´ ˇ SEN ˇ ´I KAPITOLA 3. ANALYZA A NAVRH RE
7
Pˇ r´ıkaz ActivateAt(time) zp˚ usob´ı napl´anov´an´ı ud´alosti na dobu time. Pokud bude zadan´ y ˇcas menˇs´ı, neˇz aktu´aln´ı hodnota modelov´eho ˇcasu, pˇr´ıkaz se projev´ı jako pˇr´ıkaz Activate. Pˇ r´ıkaz ActivateDelay(delay) zp˚ usob´ı napl´anov´an´ı ud´alosti na dobu time+delay (time je aktu´ aln´ı hodnota modelov´eho ˇcasu, delay je parametr pˇr´ıkazu kter´ y ud´ av´ a zpoˇzdˇen´ı oproti aktu´aln´ımu modelov´emu ˇcasu). Prioritn´ı pˇ r´ıkazy. Specifikace modelov´eho ˇcasu je stejn´a jako u pˇredchoz´ıch pˇr´ıkaz˚ u. Pˇr´ıkazy ale pouˇz´ıvaj´ı prioritn´ı pl´anov´an´ı, to znamen´a ˇze ud´alost se napl´anuje pˇred vˇsechny ud´ alosti, kter´e jsou napl´anovan´e pro tuto hodnotu modelov´eho ˇcasu. Jsou to pˇr´ıkazy ActivatePrior, ActivateAtPrior a ActivateDelayPrior. Referenˇ cn´ı pˇ r´ıkazy. Pˇr´ıkazy pl´anuj´ı ud´alost bezprostˇrednˇe pˇred, nebo za danou referenˇcn´ı ud´ alost. Jsou to pˇr´ıkazy ActivateBefore a ActivateAfter. Pˇ r´ıkaz ActivateBefore(ref event) napl´anuje ud´alost pˇred ud´alost ref event (pro stejnou hodnotu modelov´eho ˇcasu). Pˇ r´ıkaz ActivateAfter(ref event) napl´anuje ud´alost za ud´alost ref event (pro stejnou hodnotu modelov´eho ˇcasu). Syntaxe pˇr´ıkazu Reactivate je stejn´a jako u pˇr´ıkazu Activate, jsou tedy k dispozici pˇr´ıkazy: Reactivate, ReactivateAt(time), ReactivateDelay(delay), ReactivatePrior, ReactivateAtPrior (time), ReactivateDelayPrior (delay), ReactivateBefore(ref event), ReactivateAfter(ref event). Cancel slouˇz´ı k odstranˇen´ı potlaˇcen´e ud´alosti ze seznamu ud´alost´ı. Je-li pˇr´ıkaz zavol´an na pasivn´ı nebo aktivn´ı ud´ alost, tak se projev´ı jako ne´ uspˇeˇsn´ y a vr´at´ı hodnotu false. V opaˇcn´em pˇr´ıpadˇe vrac´ı true. 3.2.2
Informaˇ cn´ı metody
Informaˇcn´ı metody slouˇz´ı k z´ısk´ an´ı informac´ı o konkr´etn´ı ud´alosti. Rozhodl jsem se implementovat informaˇcn´ı metody get time a idle, kter´e jsou obsaˇzeny i v syst´emu SIMCP. D´ale jsem se rozhodl pro implementaci metody get id, kter´a slouˇz´ı k identifikaci ud´alost´ı. Metodu terminated nemˇelo smysl implementovat, protoˇze takov´ y stav je definov´an pouze pro procesy. get time vrac´ı hodnotu modelov´eho ˇcasu, na kterou je ud´alost napl´anovan´a. get id vrac´ı ˇc´ıslo, kter´e jednoznaˇcnˇe identifikuje danou ud´alost. idle vrac´ı true, pokud je ud´ alost pasivn´ı. 3.2.3
Pomocn´ e funkce
Pomocn´e funkce slouˇz´ı k z´ısk´ an´ı informac´ı o simulaˇcn´ım syst´emu. Rozhodl jsem se implementovat pomocn´e funkce current a real time, kter´e jsou obsaˇzeny v syst´emu SIMCP. D´ale jsem se rozhodl implementovat funkci set destruct, kter´a bude slouˇzit k uvolnˇen´ı dynamicky alokovan´ ych ud´ alost´ı po skonˇcen´ı simulace. current vrac´ı konstantn´ı ukazatel na aktivn´ı ud´alost. real time vrac´ı aktu´ aln´ı hodnotu simulaˇcn´ıho ˇcasu. set destruct zaznamen´ a ud´ alost do seznamu alokovan´ ych ud´alost´ı. Tyto ud´alosti budou automaticky uvolnˇeny po skonˇcen´ı simulace.
´ ´ ˇ SEN ˇ ´I KAPITOLA 3. ANALYZA A NAVRH RE
8
3.3
N´ avrh datov´ ych struktur
Datovou strukturu, kter´ a bude obsahovat vzestupnˇe setˇr´ıdˇen´e ud´alosti, je moˇzn´e navrhnout nˇekolika zp˚ usoby. V SIMCP byl seznam ud´alost´ı implementov´an obousmˇernˇe prov´azan´ ym seznamem. Velikost seznamu roste line´ arnˇe v z´avislosti na poˇctu obsaˇzen´ ych z´aznam˚ u a nen´ı omezen velikost´ı simulaˇcn´ıho ˇcasu, ani celkov´ ym poˇctem z´aznam˚ u. Jeho nev´ yhodou je ale ˇcas potˇrebn´ y k napl´ anov´ an´ı ud´ alosti. Chci-li napl´anovat ud´alost na ˇcas t, mus´ım proj´ıt n z´aznam˚ u neˇz naraz´ım na posledn´ı z´ aznam s ˇcasem t, za kter´ y potˇrebuji vloˇzit pl´anovanou ud´alost. N je z´avisl´e na poˇctu prvk˚ u obsaˇzen´ ych v seznamu s ˇcasem menˇs´ım nebo rovn´ ym t, to znamen´a ˇze m˚ uˇze b´ yt libovolnˇe velik´e, stejnˇe jako doba potˇrebn´a pro napl´anov´an´ı ud´alosti. Lepˇs´ım ˇreˇsen´ım je pouˇzit´ı pole indexovan´eho modelov´ ym ˇcasem. Ud´alosti ale nemohou b´ yt obsaˇzeny pˇr´ımo v poli, protoˇze pro kaˇzdou hodnotu modelov´eho ˇcasu m˚ uˇze b´ yt napl´anov´ano libovoln´e mnoˇzstv´ı ud´ alost´ı. Pole proto mus´ı obsahovat ukazatel na nˇejak´ y typ seznamu. Pl´anov´an´ı do seznamu implementovan´eho t´ımto zp˚ usobem je efektivnˇejˇs´ı, protoˇze nalezen´ı spr´avn´eho ˇcasov´eho pole zabere vˇzdy konstantn´ı ˇcas. Bylo by moˇzn´e pouˇz´ıt i jin´e datov´e struktury, napˇr´ıklad n-n´arn´ı strom setˇr´ıdˇen´ y podle modelov´eho ˇcasu. Takov´ a struktura je asymptoticky stejnˇe sloˇzit´a jako v´ yˇse uveden´e pole seznam˚ u. Napl´anov´an´ı prvku zde zabere konstantn´ı ˇcas. Bylo by ale potˇreba zajistit jednoznaˇcn´e poˇrad´ı pˇri vyb´ır´an´ı ud´ alost´ı se stejn´ ym ˇcasem, takˇze v d˚ usledku je implementaˇcnˇe sloˇzitˇejˇs´ı. Pro implementaci seznamu ud´ alost´ı je nejv´ yhodnˇejˇs´ı v´ yˇse uveden´a datov´a struktura pole. 3.3.1
Podrobn´ y rozbor navrˇ zen´ e struktury
Seznam ud´alost´ı bude reprezentov´ an polem ukazatel˚ u. Indexem do pole bude modelov´ y ˇcas. Pro kaˇzdou hodnotu modelov´eho ˇcasu m˚ uˇze b´ yt napl´anov´ano libovoln´e mnoˇzstv´ı ud´alost´ı. Tyto ud´alosti mus´ı b´ yt setˇr´ıdˇen´e podle toho, v jak´em poˇrad´ı byly napl´anov´any. Tˇemto poˇzadavk˚ um nejl´epe vyhovuje vytvoˇren´ı datov´e struktury fronta pro jednotliv´e hodnoty modelov´eho ˇcasu. Ukazatel v poli bude tedy ukazovat na frontu obsahuj´ıc´ı ud´alosti. Fronty budou dynamicky alokov´any jen pro ty hodnoty servisn´ıho ˇcasu, kter´e obsahuj´ı nˇejak´e ud´alosti. Fronta bude obsahovat ukazatel na prvn´ı a posledn´ı prvek, t´ım bude zajiˇstˇeno vkl´ad´ani a vyb´ır´an´ı ud´alost´ı v konstantn´ım ˇcase. Tak´e bude implementov´ano prioritn´ı vkl´ad´an´ı ud´alost´ı. D´ale zde mus´ı b´ yt zaruˇceno automatick´e prodlouˇzen´ı pole v pˇr´ıpadˇe, ˇze ud´alost bude pl´anov´ana na hodnotu modelov´eho ˇcasu, kter´ a pˇresahuje aktu´aln´ı d´elku pole. To je moˇzn´e zaruˇcit postupn´ ym zvˇetˇsov´ an´ım pole, ale pˇri tom doch´az´ı ke kop´ırov´an´ı velk´ ych blok˚ u pamˇeti. Proto je tento princip nevhodn´ y. Lepˇs´ı zp˚ usob je implementovat pole spojov´ ym seznamem pol´ı o konstant´ı d´elce. Bude li potˇreba pole prodlouˇzit, vytvoˇr´ı se nov´ y element pole, kter´ y se pˇripoj´ı za jiˇz vytvoˇren´e prvky, takˇze prodluˇzov´ an´ı pole bude mnohem rychlejˇs´ı. Proto jsem zvolil tento princip. 3.3.2
Pomocn´ e datov´ e struktury
Datovou strukturu fronty je moˇzn´e vyuˇz´ıt i v jin´ ych ˇc´astech syst´emu, napˇr´ıklad pro implementaci fronty alokovan´ ych ud´ alost´ı. Do t´eto fronty bude zapisovat navrˇzen´a funkce set destruct. Frontu tak´e m˚ uˇze potˇrebovat uˇzivatel pˇri vytv´aˇren´ı vlastn´ıch simulac´ı. Proto bude dobr´e implementovat frontu jako ˇsablonu2 . ˇ Sablona bude obsahovat metody pro vloˇzen´ı prvku na konec fronty a pro vyjmut´ı prvn´ıho prvku. D´ale mus´ı obsahovat metodu pro vloˇzen´ı prioritn´ıho prvku na zaˇc´atek fronty. Nezbytn´a bude podpora referenˇcn´ıch pˇr´ıkaz˚ u a pˇr´ıkazu Cancel. Fronta tedy bude m´ıt implementovanou metodu pro smaz´ an´ı zadan´eho prvku a metody pro vloˇzen´ı prvku pˇred nebo za referenˇcn´ı prvek. 2ˇ Sablona datov´e struktury je generick´ a struktura, pouˇziteln´ a pro vˇsechny datov´e typy. Pˇri vytv´ aˇren´ı instance je nutn´e ˇsablonu specializovat zad´ an´ım konkr´etn´ıho datov´eho typu.
´ ´ ˇ SEN ˇ ´I KAPITOLA 3. ANALYZA A NAVRH RE
3.4
9
Volba implementaˇ cn´ıho prostˇ red´ı
Pr´aci jsem se rozhodl implementovat v jazyce C++ podle normy ANSI 95. Tento jazyk jsem zvolil, protoˇze m´ am hodnˇe zkuˇsenost´ı s programov´an´ım v tomto prostˇred´ı. Jazyk je vhodn´ y k implementaci sloˇzit´ ych datov´ ych struktur, podporuje objektov´e programov´an´ı i ˇsablony. V´ ysledn´ y zdrojov´ y k´ od vytvoˇren´ y podle normy ANSI je pˇrenositeln´ y na vˇsechny bˇeˇznˇe pouˇz´ıvan´e operaˇcn´ı syst´emy. Pro v´ yvoj aplikace pouˇziji v´ yvojov´e prostˇred´ı C++BuilderX Personal Edition verze 1.0.0.1786, na kter´e m´ am ˇskoln´ı licenci.
10
KAPITOLA 4. REALIZACE
4 Realizace Simulaˇcn´ı syst´em jsem implementoval v knihovnˇe Simulation. Knihovna obsahuje header soubor1 simulation.h s deklaracemi jednotliv´ ych tˇr´ıd a ˇsablon a implementaˇcn´ı soubor simulation.cpp. J´adro syst´emu je definov´ ano v souboru start.cpp, kter´ y obsahuje i funkci main. Ud´alosti spouˇstˇen´e j´ adrem syst´emu definuje uˇzivatel v souborech uzivatel.h a uzivatel.cpp.
4.1
Knihovna simulation
ˇ Simulation obsahuje ˇsablony item<>, head<> a tˇr´ıdy array, list, event. Sablony item<> a head<> popisuj´ı prioritn´ı frontu. Tˇr´ıda list popisuje datovou strukturu seznamu ud´alost´ı a metody pro pr´aci s n´ım. Tˇr´ıda array implementuje dynamick´e pole ukazatel˚ u, vyuˇz´ıvan´e tˇr´ıdou list. Tˇr´ıda event definuje ud´ alosti, uˇzivatelsk´e rozhran´ı simulaˇcn´ıho syst´emu a funkce pro ovl´ad´an´ı seznamu ud´alost´ı j´ adrem syst´emu. 4.1.1
Implementace prioritn´ı fronty
Nad frontou budou prov´ adˇeny operace vloˇz prvek na konec nebo zaˇc´atek fronty, vyjmi prvek ze zaˇc´atku fronty a pˇr´ıpadnˇe vyhledej prvek ve frontˇe. Pro tyto operace je efektivn´ı struktura jednosmˇernˇe sv´ azan´eho seznamu, protoˇze nepotˇrebuji frontou proch´azet pozp´atku. Fronta je implementovan´ a v ˇsablon´ ach item<> a head<>. ˇ Sablona tˇ r´ıdy item<> definuje element fronty. Obsahuje ukazatel na n´asleduj´ıc´ı prvek a ukazatel na obsah. Tyto datov´e poloˇzky jsou deklarov´any jako veˇrejn´e, aby k nim mˇela pˇr´ıstup ˇsablona head<>. D´ ale je deklarov´an konstruktor, kter´ y pˇri vytvoˇren´ı nov´eho prvku napln´ı datov´e poloˇzky hodnotou NULL. Parametrem ˇsablony je typ ukazatele na obsah. ˇ Sablona tˇ r´ıdy head<> definuje hlavu prioritn´ı fronty. Obsahuje ukazatel na prvn´ı a posledn´ı element fronty. Tyto datov´e poloˇzky jsou zde jiˇz deklarov´any jako protected, to znamen´a ˇze k nima maj´ı pˇr´ıstup pouze metody t´eto tˇr´ıdy, nebo metody dˇed´ıc´ı tˇr´ıdy. Parametrem ˇsablony je stejnˇe jako u ˇsablony item<> typ ukazatele na obsah. Jsou deklarov´any n´asleduj´ıc´ı metody: add(T *c) zaˇrad´ı na konec fronty nov´ y prvek(instanci ˇsablony item), kter´ y bude obsahovat ukazatel pˇredan´ y parametrem c. Typ ukazatele T je parametr ˇsablony. add first(T *c) zaˇrad´ı prvek na zaˇc´atek fronty. add before(T *c, T *r) zaˇrad´ı prvek do fronty pˇred element, kter´ y obsahuje ukazatel r. Pokud r nen´ı obsaˇzen´ y ve frontˇe, tak se metoda projev´ı jako pr´azdn´ y pˇr´ıkaz. add after(T *c, T *r) zaˇrad´ı prvek do fronty za element, kter´ y obsahuje ukazatel r. Pokud r nen´ı obsaˇzen´ y ve frontˇe, tak se metoda projev´ı jako pr´azdn´ y pˇr´ıkaz. rem() odebere z fronty prvn´ı prvek a vr´at´ı obsah prvku, tedy dan´ y ukazatel na objekt. rem(T *r) odebere z fronty prvek kter´ y obsahuje ukazatel r. Pokud byl prvek obsaˇzen ve frontˇe, metoda vrac´ı r. V opaˇcn´em pˇr´ıpadˇe vrac´ı NULL. is empty()const vrac´ı hodnotu true v pˇr´ıpadˇe, ˇze fronta neobsahuje ˇz´adn´ y prvek. V opaˇcn´em pˇr´ıpadˇe vrac´ı false. 1
Header soubor obsahuje deklarace datov´ ych struktur a pouˇzit´ ych funkc´ı.
KAPITOLA 4. REALIZACE 4.1.2
11
Implementace seznamu ud´ alost´ı
Seznam ud´ alost´ı je implementov´ an ve tˇr´ıd´ach array a list. Tˇ r´ıda array definuje datovou strukturu pole ukazatel˚ u na fronty ud´alost´ı. Pˇri implementaci tohoto pole byla vyuˇzita struktura spojov´eho seznamu. Kaˇzd´ y element seznamu obsahuje pole konstantn´ı velikosti a ukazatel na n´asleduj´ıc´ı element. Velikost pole ud´av´a statick´ a2 y poˇcet prvk˚ u seznamu. konstanta item length. Statick´a poloˇzka item count ud´av´a celkov´ Zdrojov´ y k´ od deklarace tˇr´ıdy array: class array{ protected: const static int item_length; //delka 1 prvku static int item_count; //pocet prvku pole head<event> **ARR; //pole pointru na frontu udalosti array *next, *last; //prvni a posledni prvek public: array(); ~array(); head<event> *& operator[](int index); //operator indexovani head<event> *operator[](int index)const; }; Popis metod tˇr´ıdy array: Konstruktor vytv´ aˇr´ı nov´ y prvek seznamu, to znamen´a ˇze alokuje pole ukazatel˚ u, inicializuje vˇsechny prvky pole hodnotou NULL a ukazatel na dalˇs´ı prvek nastav´ı na hodnotu NULL. Destruktor uvoln´ı pole ukazatel˚ u v prvn´ım elementu, je li ukazatel na dalˇs´ı element nenulov´ y, zavol´ a na nˇej rekurzivnˇe destruktor. Oper´ ator indexov´ an´ı byl pˇredefinov´an k pˇr´ıstup˚ um do pole pomoc´ı nez´aporn´eho indexu. Oper´ ator vrac´ı referenci3 na ukazatel obsaˇzen´ y v poli ukazatel˚ u. Pokud se indexovan´ y ukazatel nenach´az´ı v prvn´ım elementu spojov´eho seznamu (index je vˇetˇs´ı neˇz d´elka elementu), oper´ator postupnˇe proch´az´ı dalˇs´ı prvky seznamu. Maxim´ aln´ı d´elka indexu je urˇcena hodnotou d´elka elementu × poˇcet element˚ u. Je-li pˇrekroˇcena, oper´ ator zajist´ı automatick´e prodlouˇzen´ı pole o dalˇs´ı elementy. Konstantn´ı oper´ ator indexov´ an´ı byl implementov´an, aby do pole mohly pˇristupovat 4 konstantn´ı metody jin´ ych tˇr´ıd. Obdrˇz´ı-li konstantn´ı oper´ator index vˇetˇs´ı neˇz je maxim´ aln´ı d´elka indexu, vrac´ı hodnotu NULL. Tˇ r´ıda list definuje metody pro pr´ aci se seznamem ud´alost´ı a informaˇcn´ı metody. Tyto metody budou vol´ any pl´ anovac´ımi pˇr´ıkazy a j´adrem simulaˇcn´ıho syst´emu. Tˇr´ıda obsahuje datov´e poloˇzky: • time – aktu´ aln´ı hodnota modelov´eho ˇcasu. 2
Statick´e poloˇzky jsou spoleˇcn´e vˇsem instanc´ım tˇr´ıdy. Reference je odkaz na promˇenou. Operace proveden´e nad touto referenc´ı maj´ı stejn´ yu ´ˇcinek, jako kdyby byly proveden´e pˇr´ımo s promˇenou na kterou reference odkazuje. 4 Konstant´ı metoda nem˚ uˇze mˇenit obsah instance. Metody volan´e konstantn´ı metodou mus´ı b´ yt tak´e konstantn´ı. 3
12
KAPITOLA 4. REALIZACE • max time – nejvyˇsˇs´ı hodnota modelov´eho ˇcasu, na kterou je napl´anovan´a ud´alost. • E LIST – staticky inicializovan´a instance5 tˇr´ıdy array. Tato instance reprezentuje samotn´ y seznam ud´ alost´ı. • current – ukazatel na ud´ alost, kter´a byla naposledy odebr´ana ze seznamu ud´alost´ı Pro tˇr´ıdu je definov´ an konstruktor a destruktor. Konstruktor inicializuje datov´e poloˇzky time a max time na 0 a ukazatel current na hodnotu NULL. Destruktor uvolˇ nuje fronty ud´alost´ı alokovan´e v seznamu E LIST. Metody pro pr´aci se seznamem ud´alost´ı jsou: add(event *e, unsigned int t) zaˇrad´ı ud´alost do seznamu ud´alost´ı pro modelov´ y ˇcas t na konec fronty. Pokud pro tuto hodnotu modelov´eho ˇcasu jeˇstˇe nen´ı vytvoˇrena fronta, tak ji metoda alokuje. Metoda oprav´ı poloˇzku max time v pˇr´ıpadˇe, ˇze je ud´alost vkl´ ad´ ana na hodnotu modelov´eho ˇcasu vyˇsˇs´ı neˇz je max time. add prior(event *e, unsigned int t) zaˇr´ad´ı ud´alost do seznamu ud´alost´ı pro modelov´ y ˇcas t na zaˇc´ atek fronty. Metoda t´eˇz alokuje nov´e fronty a upravuje poloˇzku max time stejnˇe jako metoda add(event *e, unsigned int t). add before(event *e, unsigned int t, event *ref ) Obsahuje-li fronta ud´alost´ı pro modelov´ y ˇcas t referenˇcn´ı ud´ alost ref, metoda zaˇrad´ı ud´alost e do fronty pˇred ud´alost ref. V opaˇcn´em pˇr´ıpadˇe se metoda projev´ı jako pr´azdn´ y pˇr´ıkaz. add after(event *e, unsigned int t, event *ref ) Obsahuje-li fronta ud´alost´ı pro modelov´ y ˇcas t referenˇcn´ı ud´ alost ref, metoda zaˇrad´ı ud´alost e do fronty za ud´alost ref. V opaˇcn´em pˇr´ıpadˇe se metoda projev´ı jako pr´azdn´ y pˇr´ıkaz. get() odstran´ı z fronty ud´ alost´ı pro aktu´aln´ı hodnotu modelov´eho ˇcasu ud´alost, kter´a je napl´ anovan´ a jako prvn´ı, aktualizuje datovou poloˇzku current a vr´at´ı ukazatel na tuto ud´ alost. Pokud pro aktu´ aln´ı hodnotu modelov´eho ˇcasu nen´ı napl´anovn´a ˇz´adn´a ud´alost, metoda vr´ at´ı hodnotu NULL. rem(event *ref, unsigned int t) smaˇze z fronty ud´alost´ı pro aktu´aln´ı hodnotu modelov´eho ˇcasu ud´ alost ref. Pokud ud´alost nen´ı ve frontˇe obsaˇzen´a, metoda vr´at´ı NULL, v opaˇcn´em pˇr´ıpadˇe vr´ at´ı ukazatel ref. get current()const vrac´ı konstantn´ı ukazatel na ud´alost, kter´a byla naposledy odebr´ana metodou get(). inc time() inkrementuje modelov´ y ˇcas. Informaˇcn´ı metody slouˇz´ı k z´ısk´ an´ı informac´ı o stavu seznamu ud´alost´ı: is event()const vrac´ı true, pokud je pro aktu´aln´ı hodnotu servisn´ıho ˇcasu napl´anov´ana nˇejak´ a ud´ alost, neboli kdyˇz je dan´a fronta ud´alost´ı nepr´azdn´a. V opaˇcn´em pˇr´ıpadˇe vrac´ı false is empty()const vrac´ı true, pokud v seznamu ud´alost´ı nan´ı napl´anovan´a ˇz´adn´a ud´alost, coˇz nast´ av´ a tehdy, kdyˇz modelov´ y ˇcas dos´ahne hodnoty max time a pro tento ˇcas jiˇz nen´ı ud´ alost. at´ı aktu´ aln´ı hodnotu modelov´eho ˇcasu. get time()const vr´ find(const event *ref, unsigned int& index) vrac´ı true, pokud seznam ud´alost´ı obsahuje ud´ alost ref. Hodnota modelov´eho ˇcasu, pro kter´ y byla ud´alost nalezena v seznamu, je vr´ acena v´ ystupn´ım parametrem index. Pokud ud´alost v seznamu nebyla nalezena, metoda vrac´ı false.
5 V C++ je moˇzn´e vytv´ aˇret instance tˇr´ıd staticky. Tyto instance maj´ı platnost v bloku, ve kter´em byly vytvoˇreny. V okamˇziku, kdy skonˇc´ı jejich platnost, jsou automaticky uvolnˇeny vol´ an´ım destruktoru.
KAPITOLA 4. REALIZACE 4.1.3
13
Implementace ud´ alost´ı
Ud´alost je instance libovoln´e tˇr´ıdy, kter´a dˇed´ı vlastnosti tˇr´ıdy event. Chov´an´ı ud´alost´ı popisuj´ı uˇzivatelem definovan´e metody t´eto tˇr´ıdy. Kaˇzd´a instance pak obsahuje ukazatel na metodu, kter´a definuje chov´ an´ı t´eto konkr´etn´ı ud´alosti. Jsou pˇreddefinov´any 2 speci´aln´ı metody, kter´e maj´ı zvl´aˇstn´ı v´ yznam. Jsou to metody run a terminate: run abstraktn´ı metoda, mus´ı b´ yt uˇzivatelem pˇredefinov´ana v uˇzivatelsk´e tˇr´ıdˇe simulation. Metoda run bude definovat prvn´ı ud´alost, kter´a se spust´ı na zaˇc´atku simulace. terminate tato metoda definuje posledn´ı ud´alost simulace. Nemus´ı b´ yt uˇzivatelem definov´ ana. Pot´e co j´ adro syst´emu spust´ı tuto ud´alost, jiˇz ˇz´adn´e dalˇs´ı ud´alosti neaktivuje. Napl´ anov´ an´ım ud´ alosti terminate tak lze explicitnˇe urˇcit konec simulace. Instance tˇr´ıdy event obsahuje tyto datov´e poloˇzky: const unsigned int id – jednoznaˇcn´a identifikace ud´alosti. unsigned int time – hodnota ˇcasu na kterou je potlaˇcen´a ud´alost napl´anovan´a bool scheduled – pokud je ud´ alost potlaˇcen´a, scheduled obsahuje hodnotu true, v opaˇcn´em pˇr´ıpadˇe obsahuje hodnotu true. void (event::* launch)() – ukazatel na metodu tˇr´ıdy event (pˇr´ıpadnˇe na metodu tˇr´ıdy kter´ a dˇed´ı vlastnosti tˇr´ıdy event). Tato metoda bude spuˇstˇena v okamˇziku, kdy se ud´alost stane aktivn´ı. Hodnoty tˇechto datov´ ych poloˇzek inicializuje konstruktor a mˇen´ı je pl´anovac´ı i obsluˇzne funkce. Statick´e datov´e poloˇzky tˇr´ıdy event jsou: unsigned int counter – slouˇz´ı pro urˇcen´ı unik´atn´ıho id pˇri inicializaci nov´ ych ud´alost´ı. head<event>qeque – staticky inicializovan´a instance ˇsablony head, jedn´a se o frontu ukazatel˚ u na ud´ alosti. Tato fronta slouˇz´ı k uvolnˇen´ı dynamicky alokovan´ ych ud´alost´ı. list LIST – staticky inicializovan´ a instance tˇr´ıdy list pˇredstavuje seznam ud´alost´ı. Tˇr´ıda d´ale definuje v´ yˇctov´ y datov´ y typ ”type”, kter´ y urˇcuje zp˚ usob pl´anov´an´ı ud´alost´ı. Pro tˇr´ıdu je implementov´ an konstruktor bez parametr˚ u a destruktor: Konstruktor vytv´ aˇr´ı ud´ alost – novou instanci tˇr´ıdy event. Nastavuje id na hodnotu poˇc´ıtadla counter, time na okamˇzitou hodnotu modelov´eho ˇcasu, promˇenou scheduled na false a ukazatel launch na hodnotu NULL. Nav´ıc inkrementuje poˇc´ıtadlo counter. Destruktor je definovan´ y jako virtu´aln´ı, aby mohl b´ yt pˇredefinov´an v nˇekter´em z potomk˚ u. 4.1.4
Implementace uˇ zivatelsk´ eho rozhran´ı
Tˇr´ıda event d´ ale implementuje uˇzivatelsk´e rozhran´ı, kter´e bylo navrˇzeno v sekci 3.2. Rozhran´ı obsahuje pl´ anovac´ı pˇr´ıkazy, informaˇcn´ı metody a pomocn´e funkce. 4.1.4.1
Pl´ anovac´ı pˇ r´ıkazy
Pl´anovac´ı pˇr´ıkazy jsou realizov´ any pomoc´ı makra Activate, kter´e vol´a metodu activate a d´ ale makrem Reactivate, kter´e vol´ a metodu reactivate. Syntaxe pl´anovac´ıch pˇr´ıkaz˚ u je: • Activate(l)
14
KAPITOLA 4. REALIZACE • ActivatePrior(l) • ActivateAt(t, l) • ActivateAtPrior(t, l) • ActivateDelay(t, l) • ActivateDelayPrior(t, l) • ActivateAfter(e, l) • ActivateBefore(e, l) • Reactivate(l) • ReactivatePrior(l) • ReactivateAt(t, l) • ReactivateAtPrior(t, l) • ReactivateDelay(t, l) • ReactivateDelayPrior(t, l) • ReactivateAfter(e, l) • ReactivateBefore(e, l)
S´emantika pl´anovac´ıch pˇr´ıkaz˚ u je podrobnˇe pops´ana v sekci 3.2.1 Metoda activate slouˇz´ı k pl´ anov´ an´ı pasivn´ıch a aktivn´ıch ud´alost´ı. M´a tyto parametry: type t je parametr v´ yˇctov´eho typu ”type”, urˇcuje zp˚ usob pl´anov´ani ud´alost´ı. unsigned int time obsahuje hodnotu modelov´eho ˇcasu, na kterou m´a b´ yt ud´alost napl´anov´ana. bool prior informuje zda m´ a b´ yt ud´ alost pl´anov´ana jako prioritn´ı event *ref obsahuje ukazatel na referenˇcn´ı potlaˇcenou ud´alost. void (event::* l)() je ukazatel na metodu, kter´a se m´a spustit kdyˇz se ud´alost stane aktivn´ı. Tento parametr se uloˇz´ı do datov´e poloˇzky launch. Metoda obsahuje pˇr´ıkaz switch, kter´ y podle obsahu parametru t ˇr´ıd´ı, jak´ ym zp˚ usobem se ud´alost napl´anuje. Parametr t m˚ uˇze nab´ yvat tˇechto hodnot: now – metoda bude napl´ anov´ ana na okamˇzitou hodnotu modelov´eho ˇcasu. at – metoda bude pl´ anov´ ana na hodnotu modelov´eho ˇcasu pˇredanou parametrem time. Jeli hodnota parametru time menˇs´ı neˇz okamˇzit´a hodnota modelov´eho ˇcasu, pouˇzije se okamˇzit´a hodnota. delay – metoda bude napl´ anov´ ana se spoˇzdˇen´ım, tedy na hodnotu urˇcenou parametrem time + aktu´ aln´ı hodnota modelov´eho ˇcasu. Pro pl´anov´an´ı ud´ alost´ı se pouˇzij´ı metody tˇr´ıdy list: add prior a add. Priorita se rozliˇsuje na z´akladˇe parametru prior. Pokud pl´ anovan´a ud´alost nen´ı potlaˇcen´a, tak je pl´anov´an´ı u ´spˇeˇsn´e a metoda vrac´ı true.
KAPITOLA 4. REALIZACE
15
before, after – Pl´ anov´ an´ı pˇred/za referenˇcn´ı ud´alost pˇredanou parametrem ref. Hodnota modelov´eho ˇcasu je z´ısk´ ana metodou find tˇr´ıdy list. Pokud referenˇcn´ı ud´alost nebyla nalezena, pl´ anov´ an´ı se neprovede a metoda activate vrac´ı hodnotu false. V opaˇcn´em pˇr´ıpadˇe se ud´ alost napl´ anuje pomoc´ı metod add before a add after tˇr´ıdy list a metoda vrac´ı true. Bˇehem pl´ anov´ an´ı se mˇen´ı datov´e sloˇzky ud´alosti: • scheduled se nastav´ı na true, pokud je pl´anov´an´ı u ´spˇeˇsn´e. • time se nastav´ı na hodnotu, na kterou je ud´alost napl´anov´ana • launch se nastav´ı na hodnotu parametru l Metoda reactivate slouˇz´ı k pl´ anov´ an´ı potlaˇcen´ ych ud´alost´ı. M´a stejn´e parametry jako metoda activate. Pokud je zavol´ ana na pasivn´ı nebo aktivn´ı ud´alost, vol´a metodu activate. Je-li zavol´ ana na potlaˇcenou ud´ alost, tak ji nejprve odebere ze seznamu ud´alost´ı a nastav´ı jej´ı parametr scheduled na hodnotu false. T´ım ji uˇcin´ı pasivn´ı. Posl´eze na tuto ud´alost vol´a metodu activate. 4.1.4.2
Informaˇ cn´ı metody
Tyto metody umoˇzn ˇuj´ı z´ısk´ avat vlastnosti jednotliv´ ych ud´alost´ı. Jsou to tyto metody: get time vrac´ı simulaˇcn´ı ˇcas, na kter´ y byla ud´alost napl´anovan´a. get id vrac´ı jednoznaˇcnou identifikaci ud´alosti. idle vrac´ı true, pokud je ud´ alost pasivn´ı. V opaˇcn´em pˇr´ıpadˇe vrac´ı false. (Ud´alost je pasivn´ı pokud nen´ı potlaˇcen´ a ani aktivn´ı, tzn. kdyˇz datov´a poloˇzka scheduled obsahuje false a metoda current ukazuje na jinou ud´alost.) 4.1.4.3
Pomocn´ e funkce
currrent tato funkce vrac´ı ukazatel na posledn´ı spuˇstˇenou ud´alost(vol´a metodu tˇr´ıdy list get current). Poloˇzka current seznamu ud´alost´ı se aktualizuje vˇzdy pˇri spouˇstˇen´ı aktivn´ı ud´alosti. V syst´emu m˚ uˇze m´ıt ˇr´ızen´ı pouze aktivn´ı ud´alost, proto je-li zavol´ana funkce current, posledn´ı spuˇstˇen´ a ud´ alost mus´ı b´ yt aktivn´ı. real time funkce vrac´ı okamˇzitou hodnotu simulaˇcn´ıho ˇcasu(vol´a metodu get time tˇr´ıdy list). set destruct funkce zaˇrad´ı ukazatel na objekt do fronty qeque(v´ yˇse popsan´a statick´a datov´ a poloˇzka tˇr´ıdy event). 4.1.5
Implementace obsluˇ zn´ eho rozhran´ı
Obsluˇzn´e rozhran´ı seznamu ud´ alost´ı je vyuˇz´ıv´ano j´adrem simulaˇcn´ıho syst´emu. Metody rozhran´ı umoˇzn ˇuj´ı zjistit stav, v jak´em se seznam ud´alost´ı nach´az´ı, d´ale odebr´an´ı ud´alosti ze seznamu a jej´ı n´asledn´e spuˇstˇen´ı. is event pokud je pro aktu´ aln´ı hodnotu modelov´eho ˇcasu napl´anovan´a nˇejak´a ud´alost, metoda vrac´ı hodnotu true, v opaˇcn´em pˇr´ıpadˇe vrac´ı false. is empty vrac´ı true v pˇr´ıpadˇe, ˇze simulaˇcn´ı ˇcas dos´ahnul hodnoty max time(nejzaˇsˇs´ı ˇcas na kter´ y byla napl´ anov´ ana nˇejak´ a ud´alost) a nen´ı jiˇz napl´anov´ana ˇz´adn´a ud´alost. Pokud je hodnota simulaˇcn´ıho ˇcasu niˇzˇs´ı neˇz max time, metoda vrac´ı false. get event tato metoda odebere ud´alost ze seznamu ud´alost´ı a nastav´ı poloˇzku scheduled na false, to znamen´ a ˇze uˇcin´ı ud´ alost pasivn´ı. Metoda vrac´ı ukazatel na odebranou ud´alost.
16
KAPITOLA 4. REALIZACE
launch event metoda zp˚ usob´ı spuˇstˇen´ı ud´alosti, na kterou je zavol´ana(vol´a metodu, na kterou ukazuje ukazatel launch). is terminate metoda vrac´ı true, pokud je vol´ana nad ud´alost´ı terminate, tedy pokud ukazatel launch dan´e ud´ alosti ukazuje na metodu terminate. inc time metoda zp˚ usob´ı zv´ yˇsen´ı simulaˇcn´ıho ˇcasu o 1. destruct metoda postupnˇe uvoln´ı vˇsechny objekty zaˇrazen´e ve frontˇe qeque.
4.2
J´ adro syst´ emu
J´adro syst´emu je definov´ ano ve funkci main v souboru start.cpp. Pˇri spuˇstˇen´ı simulace j´adro nejprve vytvoˇr´ı instanci tˇr´ıdy simulation. Tato instance se pomoc´ı pˇr´ıkazu Activate s parametrem run napl´ anuje do seznamu ud´ alost´ı pro ˇcas 0. Pˇr´ıkaz zp˚ usob´ı napl´anov´an´ı poˇc´ateˇcn´ı ud´alosti run. Pot´e se spouˇst´ı hlavn´ı cyklus j´adra. Ten vˇzdy odebere ud´alost, kter´a je na ˇradˇe a spust´ı ji. Pokud pro okamˇzitou hodnotu simulaˇcn´ıho ˇcasu jiˇz nen´ı ˇz´adn´a ud´alost, simulaˇcn´ı ˇcas se inkrementuje o 1. Cyklus se ukonˇc´ı v pˇr´ıpadˇe, ˇze skonˇcila ud´alost terminate, kter´a explicitnˇe urˇcuje konec simulace, nebo pokud jiˇz nejsou napl´anov´any ˇz´adn´e ud´alosti(metoda is empty vrac´ı hodnotu true). N´ asleduje vol´ an´ı metody destruct, kter´a uvoln´ı pˇr´ıpadn´e alokovan´e ud´alosti a uvolnˇen´ı ud´alosti run. Zde je popsan´ y zdrojov´ y k´od j´adra: event *first, *e; bool term_sim=false; first=new simulation; first->Activate(simulation::run);
//naplanuj pocatecni udalost
while(!event::is_empty() && !term_sim){ //hlavni cyklus simulace while(event::is_event()) //spusteni udalosti naplanovanych pro tento cas { e=event::get_event(); //odeber udalost ze seznamu e->launch_event(); // a spust ji if(e->is_terminate()){term_sim=true; break;} //byla li to udalost terminate->ko } event::inc_time(); //zvys servisni cas o 1 } event::destruct(); delete first;
//uvolni alokovane udalosti
´ ´I KAPITOLA 5. TESTOVAN
17
5 Testov´ an´ı Pro ovˇeˇren´ı funkˇcnosti implementovan´eho simulaˇcn´ıho syst´emu jsem se rozhodl vytvoˇrit dvˇe simulace. Prvn´ı simulace pˇredstavuje typick´ y syst´em hromadn´e obsluhy – simulace vyt´ıˇzenosti obvodn´ıch l´ekaˇr˚ u. Druh´ a simulace modeluje jednoduch´ y logick´ y obvod sestaven´ y ze tˇr´ı hradel.
5.1
Simulace vyt´ıˇ zenosti l´ ekaˇ r˚ u
Typick´ ym probl´emem ˇcesk´eho zdravotnictv´ı je nedostatek l´ekaˇr˚ u. N´asleduj´ıc´ı simulace nastiˇ nuje situaci, kter´ a vznik´ a v ˇcek´ arnˇe obvodn´ıho l´ekaˇre. M´ame l´ekaˇrsk´e zaˇr´ızen´ı, ve kter´em si zaˇr´ıdili ordinace tˇri obvodn´ı l´ekaˇri. Pacienti jsou pˇrihl´aˇseni vˇzdy k nˇekter´emu z l´ekaˇr˚ u. Pacient m˚ uˇze onemocnˇet r˚ uzn´ ymi nemocemi, pˇriˇcemˇz oˇsetˇren´ı z´avaˇzn´e nemoci trv´ a d´ele neˇz bˇeˇzn´e oˇsetˇren´ı. Kaˇzd´ y l´ekaˇr m´a svoji vlastn´ı ˇcek´arnu. Budu pˇredpokl´ adat pˇr´ıchod nov´eho pacienta do nˇekter´e z ˇcek´aren nejpozdˇeji do 10 min. od pˇr´ıchodu posledn´ıho nemocn´eho, pˇriˇcemˇz pˇr´ısluˇsnost k l´ekaˇri a druh onemocnˇen´ı bude zvolen n´ahodnˇe. D´ale budu pˇredpokl´ adat, ˇze l´ekaˇri pˇrij´ımaj´ı nov´eho pacienta ihned po propuˇstˇen´ı oˇsetˇren´eho. Pacienti budou do ˇcek´ arny chodit aˇz do ˇcasu urˇcen´eho konstantou konec simulace, kter´ a pˇredstavuje konec ordinaˇcn´ıch hodin l´ekaˇre. Ukonˇcen´ı simulace ale nastane aˇz l´ekaˇri obslouˇz´ı vˇsechny pacienty, kter´e maj´ı v ˇcek´ arnˇe. 5.1.1
Realizace modelu
V modelu doch´ az´ı ke tˇrem r˚ uzn´ ym ud´alostem: • pˇr´ıchod pacienta do ˇcek´ arny • pˇrijet´ı pacienta l´ekaˇrem • propuˇstˇen´ı oˇsetˇren´eho pacienta Tyto ud´alosti pop´ıˇsi ve tˇr´ıdˇe pacienti, kter´a dˇed´ı vlastnosti tˇr´ıdy event. Ve tˇr´ıdˇe simulation, kter´a t´eˇz dˇed´ı tˇr´ıdu event, budu definovat speci´aln´ı ud´alost run – zaˇc´atek simulace a terminate – konec simulace. Pro deklaraci poˇzadavku pouˇziji tˇr´ıdu pacient a kan´al obsluhy bude pops´ an ve tˇr´ıdˇe l´ekaˇr. Pro v´ ystup informac´ı o obsazenosti l´ekaˇr˚ u nap´ıˇsi tˇr´ıdu obsazenost. 5.1.1.1
Implementace datov´ ych struktur
Druhy nemoc´ı implementuji v´ yˇctov´ ym typem enum. Budu uvaˇzovat tyto nemoci: • nachlazen´ı (5) • ang´ına (10) • chˇripka (10) • z´apal plic (15) • ˇzloutenka (20) • mal´ arie (30) V z´avorce uv´ ad´ım pˇredpokl´ adanou dobu oˇsetˇren´ı v minut´ach.
´ ´I KAPITOLA 5. TESTOVAN
18
Poˇ zadavek je v naˇsem modelu pacient. Je pops´an tˇr´ıdou pacient a obsahuje datov´e poloˇzky: id identifikace pacienta. id lekare poloˇzka urˇcuje, ke kter´emu l´ekaˇri je pacient pˇrihl´aˇsen. nemoc poloˇzka urˇcuje, jakou nemoc´ı pacient trp´ı. Je definov´ an konstruktor, kter´ y inicializuje datov´e poloˇzky a metoda vypis, kter´a vyp´ıˇse id pacienta a druh nemoci. Pacienti budou bˇehem simulace ˇrazeni do fronty pacient˚ u. Fronta pacient˚ u bude vytvoˇrena pro kaˇzd´eho l´ekaˇre jedna a z d˚ uvodu snadn´eho pˇr´ıstupu budou uloˇzeny v jedn´e glob´aln´ı promˇen´e typu pole. Indexem do pole bude id l´ekaˇre. Kan´ al obsluhy je v naˇsem modelu l´ekaˇr. Je pops´an tˇr´ıdou l´ekaˇr. M˚ uˇze se nach´azet ve stavu obsazen, voln´ y nebo ukonˇcen. Je-li l´ekaˇr voln´ y, ˇcek´a aˇz mu pˇrijde jeho pacient. Je-li obsazen, tak pr´ avˇe oˇsetˇruje pacienta. Do stavu ukonˇcen se l´ekaˇr pˇrepne tehdy, pokud simulaˇcn´ı ˇcas je vˇetˇs´ı neˇz konstanta konec simulace a jeho ˇcek´arna je pr´azdn´a. Tˇr´ıda l´ekaˇr obsahuje datov´e poloˇzky: id identifikace l´ekaˇre y poˇcet oˇsetˇren´ ych pacient˚ u od zaˇc´atku simulace. poc osetrenych celkov´ vysetruje logick´ a promˇen´ a1 , ˇr´ık´ a zda l´ekaˇr pr´avˇe oˇsetˇruje nebo ˇcek´a na dalˇs´ıho pacienta(m´ a pr´ azdnou ˇcek´ arnu). konec logick´ a promˇen´ a, je li true, znamen´a ˇze l´ekaˇr uˇz pˇrestal ordinovat(skonˇcila mu pracovn´ı doba a nem´ a v ˇcek´ arnˇe jiˇz ˇz´adn´eho pacienta). zacal vysetrovat v pˇr´ıpadˇe ˇze l´ekaˇr pr´avˇe oˇsetˇruje pacienta, promˇen´a ud´av´a zaˇc´atek oˇsetˇren´ı. doba osetreni v pˇr´ıpadˇe ˇze l´ekaˇr pr´avˇe oˇsetˇruje pacienta, promˇen´a ˇr´ık´a jak dlouho bude oˇsetˇren´ı trvat. obet ukazatel na pacienta, kter´eho l´ekaˇr oˇsetˇruje. Metody pro pr´ aci s kan´ alem obsluhy jsou: Metoda vysetri pacienta pˇrepne kan´al obsluhy do stavu obsazen. Parametry metody jsou ukazatel na pacienta, simulaˇcn´ı ˇcas zaˇc´atku oˇsetˇren´ı a doba trv´an´ı oˇsetˇren´ı. Poloˇzku vysetruje metoda nastav´ı na true, ostatn´ı poloˇzky jsou nastaveny zkop´ırov´ an´ım parametr˚ u metody. Metoda propust pacienta vyp´ıˇse u ´daje o pacientovi a dobˇe oˇsetˇren´ı, zap´ıˇse z´aznam o pracovn´ım u ´konu do instance tˇr´ıdy obsazenost, uvoln´ı pacienta, inkrementuje poˇcet oˇsetˇren´ ych pacient˚ u a pˇrepne l´ekaˇre do stavu voln´ y. Metoda skonci pˇrepne l´ekaˇre do stavu ukonˇcen. D´ale jsou k dispozici metody slouˇz´ıc´ı k z´ısk´an´ı informac´ı o kan´alu obsluhy. Jsou to: get pocet – vrac´ı poˇcet obslouˇzen´ ych pacient˚ u. vysetruje pacienta – vrac´ı true, pokud je kan´al obsluhy ve stavu obsazen. skoncil – vrac´ı true, pokud je kan´ al obsluhy ve stavu ukoncen. konec osetreni – vrac´ı true, pokud m´a l´ekaˇr ukonˇcit oˇsetˇren´ı pacienta, tedy kdyˇz zaˇc´atek oˇsetˇren´ı + doba oˇsetˇren´ı odpov´ıdaj´ı aktu´aln´ı hodnotˇe simulaˇcn´ıho ˇcasu. 1
Promˇen´ a typu bool, obsahuje hodnotu true nebo false.
´ ´I KAPITOLA 5. TESTOVAN
19
V simulaci budou vytvoˇreny tˇri instance tˇr´ıdy l´ekaˇr, kter´e budou m´ıt id 0 – 2. Budou alokov´ any v glob´ aln´ı promˇen´e l´ekaˇri, kter´a je typu pole. Indexem do pole bude id l´ekaˇre. V´ ystup informac´ı podporuje tˇr´ıda obsazenost. Tˇr´ıda obsahu je dvˇe fronty z´aznam˚ u: fronta zamestnan obsahuje z´aznamy, kdy byl l´ekaˇr obsazen. fronta volny obsahuje z´ aznamy kdy l´ekaˇr nepracoval, neboli ˇcekal na pacienta. Tˇr´ıda d´ ale obsahuje promˇen´e zacatek a konec, kter´e ud´avaj´ı, v jak´em simulaˇcn´ım ˇcase l´ekaˇr naposledy zaˇcal pracovat bez pˇreruˇsen´ı a kdy skonˇcil. Metody pro pr´aci se z´aznamy jsou: Metoda obsazen slouˇz´ı k zaps´an´ı pracovn´ıho u ´konu l´ekaˇre, tedy kdy l´ekaˇr vyˇsetˇroval pacienta. Metoda m´ a parametry zaˇc´atek a konec pracovn´ıho u ´konu. Pomoc´ı tˇr´ıdn´ıch datov´ ych poloˇzek zaˇc´ atek a konec metoda zjist´ı, zda nov´ y pracovn´ı u ´kon prodluˇzuje pˇredch´ azej´ıc´ı pr´ aci, a v tom pˇr´ıpadˇe aktualizuje posledn´ı z´aznam ve frontˇe obsazen. Druh´ a moˇznost je, ˇze l´ekaˇr pˇred zapoˇcet´ım pracovn´ıho u ´konu urˇcitou dobu nebyl obsazen – ˇcekal na nov´eho pacienta. Tehdy metoda pˇrid´a nov´e z´aznamy jak do tˇr´ıdy volny, tak i do tˇr´ıdy obsazen. V obou pˇr´ıpadech se aktualizuj´ı datov´e poloˇzky zaˇc´ atek a konec. Metoda vypis slouˇz´ı k vyps´an´ı z´aznam˚ u o obsazenosti l´ekaˇre. Metoda nejprve vyp´ıˇse frontu zamestnan, kter´ a obsahuje z´aznamy, v jak´ ych ˇcasov´ ych intervalech l´ekaˇr pracoval nepˇretrˇzitˇe. Pot´e metoda vyp´ıˇse frontu volny, kter´a naopak obsahuje z´aznamy, v jak´ ych ˇcasov´ ych u ´sec´ıch l´ekaˇr nepracoval. Na z´avˇer metoda vyp´ıˇse celkov´ y souˇcet, tedy kolik minut l´ekaˇr pracoval a jak dlouho odpoˇc´ıval. 5.1.1.2
Implementace ud´ alost´ı
Pˇ r´ıchod pacienta do ˇ cek´ arny Tato ud´alost se provede tehdy, kdyˇz je modelov´ y ˇcas menˇs´ı neˇz konstanta konec simulace. Nejprve se vygeneruj´ı parametry nov´eho pacienta – n´ahodnˇe urˇc´ım jednoho ze tˇr´ı l´ekaˇr˚ u, kter´ y mu bude pˇridˇelen a jednu ze ˇsesti nemoc´ı. Pot´e alokuji nov´eho pacienta s vygenerovan´ ymi parametry. Nov´eho pacienta pˇrid´am do ˇcek´ arny pˇr´ısluˇsn´eho l´ekaˇre. Nakonec n´ ahodnˇe vygeneruji dobu 0 aˇz 10 minut a napl´anuji pˇr´ıchod nov´eho pacienta za tuto dobu (pˇr´ıkaz ActivateDelay). Pˇ rijet´ı pacienta l´ ekaˇ rem – pomoc´ı cyklu for nejprve najdu prvn´ıho l´ekaˇre, kter´ y je voln´ y. Pokud m´ a l´ekaˇr pr´ azdnou ˇcek´ arnu a simulaˇcn´ı ˇcas je menˇs´ı neˇz konstanta konec simulace, napl´ anuji pˇrijet´ı pacienta za n´ahodnˇe vygenerovanou dobu 5 – 10 minut. V opaˇcn´em pˇr´ıpadˇe z ˇcek´ arny odeberu pacienta, kter´ y je pr´avˇe na ˇradˇe. Dobu oˇsetˇren´ı urˇc´ım z pˇredpokl´ adan´e doby oˇsetˇren´ı, kter´a je definov´ana druhem nemoci kterou pacient trp´ı. K t´eto dobˇe pˇriˇc´ıt´ am n´ ahodnˇe generovan´ y ˇcas v intervalu (-2 ; 2) minut, protoˇze kaˇzd´e oˇsetˇren´ı je individu´ aln´ı a trv´ a r˚ uznˇe dlouho. Nakonec nastav´ım l´ekaˇre do stavu obsazen a pomoc´ı pˇr´ıkazu ActivateDelay napl´anuji propuˇstˇen´ı pacienta. V pˇr´ıpadˇe, ˇze l´ekaˇr mˇel pr´ azdnou ˇcek´arnu a simulaˇcn´ı ˇcas byl vˇetˇs´ı neˇz konstanta koa nec simulace, tak se l´ekaˇr pˇrepne do stavu ukonˇcen a dekrementuje se glob´aln´ı promˇen´ poˇcet l´ekaˇr˚ u. Pokud se jednalo o posledn´ıho pracuj´ıc´ıho l´ekaˇre, napl´anuje se ud´alost terminate. Zdrojov´ y k´ od ud´ alosti pˇrijet´ı pacienta l´ekaˇrem: for(int i=0; i<3; i++) //najdi volneho lekare if(!lekari[i]->vysetruje_pacienta()){ //lekar je volny
´ ´I KAPITOLA 5. TESTOVAN
20
if(!cekarna[i]->is_empty()){ //cekarna neni prazdna pacient *pac=cekarna[i]->rem(); //odeber pacienta z cekarny int osetreni=doba_osetreni(pac);//urci dobu osetreni //osetri noveho pacienta lekari[i]->vysetri_pacienta(pac, get_time(), osetreni); //naplanuj propusteni pacienta this->ActivateDelay(osetreni, pacienti::propusteni_pac); return; //konec udalosti } else if(get_time()
ActivateDelay(kontrola_cekarny, pacienti::prijem_pac); return; //konec udalosti } else //konec simulace {if(!lekari[i]->skoncil()) //ukonci lekare {pocet_lekaru--; lekari[i]->skonci(); if(pocet_lekaru)return; } if(!pocet_lekaru){ //posledni lekar naplanuje konec simulation *s=new simulation; s->Activate(simulation::terminate); set_destruct(s); return; } } } Propuˇ stˇ en´ı pacienta – pomoc´ı cyklu for nejprve najdu prvn´ıho l´ekaˇre, kter´ y je obsazen´ ya ’ pr´avˇe m´a konˇcit oˇsetˇren´ı. Na l´ekaˇre zavol´am metodu propust pacienta, kter´a zp˚ usob´ı ˇze se l´ekaˇr pˇrepne do stavu voln´ y. Nakonec napl´anuji pˇrijet´ı nov´eho pacienta na okamˇzitou hodnotu modelov´eho ˇcasu. Ud´ alost run tato ud´ alost se spust´ı na zaˇc´atku simulace jako prvn´ı. Nejprve inicializuje datov´e struktury. Alokuje kan´ aly obsluhy, fronty poˇzadavk˚ u a seznamy z´aznam˚ u o obsazenosti. Glob´ aln´ı promˇenou poˇcet l´ekaˇr˚ u nastav´ı na hodnotu 3. Pot´e napl´anuje ud´alost pˇr´ıchod pacienta na okamˇzitou hodnotu simulaˇcn´ıho ˇcasu. Ud´alost pˇr´ıjem pacienta pl´anuje se spoˇzdˇen´ım 10 oproti okamˇzit´e hodnotˇe modelov´eho ˇcasu. Tato ud´alost je napl´anov´a tˇrikr´at, pro kaˇzd´ y kan´ al obsluhy jednou. Vˇsechny napl´anovan´e ud´alosti jsou zaps´any metodou set destruct do fronty alokovan´ ych objekt˚ u. Po skonˇcen´ı simulace budou ud´alosti uvolnˇeny. Zdrojov´ y k´ od ud´ alosti run: for(int i=0; i<3; i++){ //inicializace dat.struktur lekari[i]=new lekar(i); cekarna[i]=new head<pacient>; zaznamy[i]=new obsazenost; } pocet_lekaru=3;
´ ´I KAPITOLA 5. TESTOVAN
21
pacienti *p=new pacienti; //naplanovani udalosti p->Activate(pacienti::prichod_pac); set_destruct(p); for(int i=0; i<3; i++){ p=new pacienti; p->ActivateDelay(10, pacienti::prijem_pac); set_destruct(p);} Ud´ alost terminate tato ud´ alost se spust´ı jako posledn´ı. Vyp´ıˇse informace o l´ekaˇr´ıch – seznamy obsazenosti, kter´e obsahuj´ı informace v jak´em ˇcase l´ekaˇri oˇsetˇrovali a kdy ˇcekali na pacienty a informace o poˇctu oˇsetˇren´ ych pacient˚ u. Ud´alost uvoln´ı alokovan´e kan´ aly obsluhy, fronty poˇzadavk˚ u a seznamy z´aznam˚ u. 5.1.2
Testov´ an´ı modelu
Pro otestov´ an´ı vytvoˇren´eho modelu jsem zvolil ˇskoln´ı server solaris1. Zdrojov´ y k´od jsem kompiloval pomoc´ı pˇrekladaˇce g++ s argumenty ansi, Wall, pedantic2 . Testoval jsem spr´avnost v´ ystupu a sloˇzitost programu. Pro zjiˇstˇen´ı sloˇzitosti jsem pouˇzil utilitu time, kter´a pˇresnˇe mˇeˇr´ı dobu prov´ adˇen´ı programu, tedy bez reˇzie syst´emu. Mˇeˇren´ı jsem prov´adˇel pro dobu simulace urˇcenou konstantou max time v rozmez´ı 1000 – 100000. Namˇeˇren´e hodnoty jsem zpracoval do grafu pomoc´ı n´ astroje pro tvorbu graf˚ u na ˇskoln´ım serveru herodes. Tento n´astroj mi tak´e urˇcil sloˇzitost modelu. Zjiˇstˇen´ a sloˇzitost: f (n) = 3, 28 ∗ 10−7 x2 + 0, 01x
5000
Slozitost simulace
4500 4000
user time (ms)
3500 3000 2500 2000 1500 1000 500 0 0
10000
20000
30000
40000
50000 60000 max time
70000
80000
90000
100000
Obr´ azek 5.1: Graf sloˇzitosti modelu 2
Zadan´e argumenty zp˚ usob´ı pˇreklad podle normy ansi s kompletn´ım zobrazen´ım varovn´ ych hl´ aˇsen´ı.
´ ´I KAPITOLA 5. TESTOVAN
22
Zjiˇstˇen´a sloˇzitost m´ a kvadratick´ y ˇclen. To je zp˚ usobeno t´ım, ˇze seznam ud´alost´ı je spojov´ ym seznamem pol´ı. Poˇcet element˚ u spojov´eho seznamu, pˇres kter´e mus´ı oper´ator indexov´an´ı iterovat, aby nalezl hledanou ud´ alost, z´ avis´ı na hodnotˇe simulaˇcn´ıho ˇcasu, na kterou byla ud´alost napl´anov´ana. Se zvˇetˇsuj´ıc´ı se hodnotou maxim´aln´ıho simulaˇcn´ıho ˇcasu pouˇzit´eho v simulaci se tedy zvˇetˇsuje n´ aroˇcnost nalezen´ı ud´ alosti. Tento fakt zp˚ usobil, ˇze sloˇzitost simulace z´avis´ı kvadraticky na maxim´ aln´ı hodnotˇe simulaˇcn´ıho ˇcasu. Velikost kvadratick´eho ˇclenu sloˇzitosti u simulac´ı s velikou hodnotou maxim´ aln´ıho simulaˇcn´ıho ˇcasu lze omezit prodlouˇzen´ım elementu spojov´eho seznamu (konstanta item length v souboru simulation.cpp). Uk´azka v´ ystupu pro d´elku max time = 100:
Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient Pacient
c: c: c: c: c: c: c: c: c: c: c: c: c: c: c: c: c: c:
0 s nemoci: chripka byl lekarem c: 0 prijat v: 10 a propusten v: 19 1 s nemoci: angina byl lekarem c: 1 prijat v: 10 a propusten v: 20 3 s nemoci: zapal_plic byl lekarem c: 1 prijat v: 20 a propusten v: 37 2 s nemoci: zloutenka byl lekarem c: 0 prijat v: 19 a propusten v: 40 7 s nemoci: zapal_plic byl lekarem c: 1 prijat v: 37 a propusten v: 53 6 s nemoci: zloutenka byl lekarem c: 2 prijat v: 34 a propusten v: 54 4 s nemoci: zloutenka byl lekarem c: 0 prijat v: 40 a propusten v: 58 8 s nemoci: angina byl lekarem c: 1 prijat v: 53 a propusten v: 62 10 s nemoci: angina byl lekarem c: 2 prijat v: 54 a propusten v: 64 5 s nemoci: chripka byl lekarem c: 0 prijat v: 58 a propusten v: 69 9 s nemoci: chripka byl lekarem c: 1 prijat v: 62 a propusten v: 71 15 s nemoci: chripka byl lekarem c: 0 prijat v: 83 a propusten v: 91 14 s nemoci: angina byl lekarem c: 2 prijat v: 84 a propusten v: 92 11 s nemoci: angina byl lekarem c: 1 prijat v: 84 a propusten v: 94 12 s nemoci: nachlazeni byl lekarem c: 1 prijat v: 94 a propusten v: 98 16 s nemoci: angina byl lekarem c: 0 prijat v: 91 a propusten v: 100 13 s nemoci: chripka byl lekarem c: 1 prijat v: 98 a propusten v: 109 17 s nemoci: angina byl lekarem c: 0 prijat v: 100 a propusten v: 112
lekar c: 0 obsazeny: 10-69, 83-112, volny: 0-10, 69-83, celkem odpracoval: 88, odpocival: 24, osetril: 7 pacientu. lekar c: 1 obsazeny: 10-71, 84-109, volny: 0-10, 71-84, celkem odpracoval: 86, odpocival: 23, osetril: 8 pacientu. lekar c: 2 obsazeny: 34-64, 84-92, volny: 0-34, 64-84, celkem odpracoval: 38, odpocival: 54, osetril: 3 pacientu.
´ ´I KAPITOLA 5. TESTOVAN
5.2
23
ˇ ıslicov´ C´ y obvod na u ´ rovni hradel
Budu modelovat jednoduch´ y ˇc´ıslicov´ y obvod podle obr´azku 5.2. Obvod obsahuje hradlo A typu NAND a hradlo B typu OR. Vstupy oznaˇc´ım i1, i2, i3 a v´ ystupy u, v. Budu uvaˇzovat pr˚ ubˇehy vstupn´ıch sign´ al˚ u zobrazen´e na obr´ azku 5.3. Pˇrepokl´ad´am spoˇzdˇen´ı hradla A 1ms a spoˇzdˇen´ı hradla B 2ms.
Obr´ azek 5.2: Schema ˇc´ıslicov´eho obvodu
5.2.1
Realizace modelu
Jednotliv´e sekvence vstupn´ıch sign´al˚ u pop´ıˇsi pomoc´ı samostatn´ ych tˇr´ıd signal i1, signal i2, u. Chov´ an´ı signal i3. Tyto tˇr´ıdy budou obsahovat ud´alosti, popisuj´ıc´ı zmˇeny vstupn´ıch sign´al˚ logick´ ych ˇclen˚ u pop´ıˇsi pomoc´ı ud´ alost´ı vstupn´ı a v´ ystupn´ı aktivita, kter´e definuji ve tˇr´ıd´ ach: nand in, nand out, or in, or out. Okamˇzit´e hodnoty vstupn´ıch sign´al˚ u i1, i2, i3 a v´ ystupn´ıch sign´al˚ u u, v budou uloˇzeny v glob´ aln´ıch promˇen´ ych. Ud´alosti simuluj´ıc´ı chov´an´ı logick´ ych ˇclen˚ u budou aktivov´ any podle potˇreby, proto deklaruji glob´aln´ı ukazatele na tyto ud´alosti: A in, A out, B in, B out. 5.2.1.1
Implementace vstupn´ıch sign´ al˚ u
Pr˚ ubˇehy vstupn´ıch sign´ al˚ u i1, i2, i3 pop´ıˇsi pomoc´ı tˇr´ıd signal i1, signal i2, signal i3. Kaˇzd´ a zmˇena sign´ alu z 0 na 1 nebo obr´ acenˇe v dan´em modelov´em ˇcase bude pops´ana jednou ud´alost´ı. Poˇc´ateˇcn´ı ud´ alosti budou napl´ anov´ any na zaˇc´atku simulace ud´alost´ı run. Pot´e vˇzdy, kdyˇz se aktivuje ud´ alost a zmˇen´ı hodnotu vstupn´ıho sign´alu, tak napl´anuje tak´e vstupn´ı aktivitu logick´eho ˇclenu, kter´eho ovlivnila a n´ asleduj´ıc´ı zmˇenu vstupn´ıho sign´alu (n´asleduj´ıc´ı ud´alost). Ud´alosti kter´e mˇen´ı vstupn´ı sign´ aly budu znaˇcit slovem cycle a poˇradov´ ym ˇc´ıslem, napˇr cycle 1.
´ ´I KAPITOLA 5. TESTOVAN
24
Obr´ azek 5.3: Pr˚ ubˇehy vstupn´ıch sign´al˚ u
Prvn´ı ud´alost sign´ alu i1 nastav´ı u ´roveˇ n sign´alu na logickou 0, vytiskne okamˇzit´e hodnoty sign´al˚ u, aktivuje vstupn´ı aktivitu hradla A a napl´anuje dalˇs´ı zmˇenu sign´alu, tedy ud´alost cycle 2 na hodnotu modelov´eho ˇcasu 10. Zdrojov´ y k´od ud´alosti:
void signal_i1::cycle_1() { i1=false; print(get_time()); A_in->Activate(nand_in::change_in); ActivateAt(10, signal_i1::cycle_2); }
Ostatn´ı ud´alosti popisuj´ıc´ı zmˇeny vstupn´ıch sign´al˚ u jsou naps´any analogicky.
´ ´I KAPITOLA 5. TESTOVAN 5.2.1.2
25
Implementace logick´ ych ˇ clen˚ u
Vstupn´ı aktivitu hradla A typu NAND popisuji ve tˇr´ıdˇe nand in. Tˇr´ıda obsahuje datovou poloˇzku state, kter´ a obsahuje hodnotu, kter´a je na v´ ystupu logick´eho ˇclenu, nebo tam za urˇcitou dobu, danou spoˇzdˇen´ım logick´eho ˇclenu, bude. D´ale je implementov´an konstruktor, kter´ y nastav´ı promˇenou state na poˇc´ateˇcn´ı hodnotu logick´a 0 a informaˇcn´ı metoda get, kter´ a vrac´ı hodnotu promˇen´e state. Je-li aktivov´ ana ud´ alost change in, tak se nejprve spoˇcte okamˇzit´a hodnota logick´e funkce nand(i1,i2). Pokud nov´ y stav souhlas´ı s promˇenou state, tak nen´ı potˇreba mˇenit hodnotu v´ ystupn´ıho sign´ alu u a ud´ alost se ukonˇc´ı (stane se pasivn´ı). V opaˇcn´em pˇr´ıpadˇe se state zmˇen´ı na novou hodnotu. Tehdy mohou nastat dva pˇr´ıpady: • Ud´ alost change out je potlaˇcen´a, to znamen´a ˇze logick´ y ˇclen mˇel napl´anovanou zmˇenu v´ ystupn´ıho sign´ alu u na p˚ uvodn´ı hodnou promˇen´e state. Protoˇze se ale nyn´ı promˇen´ a state zmˇenila na opaˇcnou hodnotu, tak jiˇz nen´ı d˚ uvod mˇenit v´ ystup u a proto ud´ alost zruˇs´ı napl´ anovanou ud´alost change out pomoc´ı metody cancel. • Ud´ alost change out je pasivn´ı(neboli idle = true). To znamen´a ˇze je tˇreba zmˇenit hodnotu v´ ystupn´ıho sign´alu u za dobu danou spoˇzdˇen´ım hradla A, napˇr. pomoc´ı pˇr´ıkazu ActivateDelay. Zdrojov´ y k´ od ud´ alosti change in: void nand_in::change_in() {bool new_state= !(i1 && i2); if(new_state==state)return; //zadna zmena else {state=new_state; if(A_out->idle()) //pokud nepreklapi, naplanuj preklopeni A_out->ActivateDelay(delay_a, nand_out::change_out); else cancel(A_out);} //v opacnem pripade stornuj preklopeni } V´ ystupn´ı aktivitu hradla A popisuji ve tˇr´ıdˇe nand out. Tˇr´ıda obsahuje ud´alost change out. Je-li aktivov´ ana tato ud´ alost, tak se v´ ystupn´ı sign´al u nastav´ı na hodnotu poloˇzky state ve tˇr´ıdˇe nand in a vytisknou se okamˇzit´e hodnoty vˇsech sign´al˚ u. Protoˇze ale v´ ystupn´ı sign´ al u je z´ aroveˇ n vstupn´ı sign´ al pro hradlo B, aktivuje se tak´e ud´alost change in hradla B. Zdrojov´ y k´ od ud´ alosti change out: void nand_out::change_out() {u=A_in->get(); print(get_time()); //vytiskni zmenu stavu B_in->Activate(or_in::change_in); //aktivuj nasledujici hradlo } Vstupn´ı a v´ ystupn´ı ud´ alost hradla B jsou naps´any analogicky s t´ım rozd´ılem, ˇze aktivita change in pouˇz´ıv´ a logickou funkci or. 5.2.1.3
Implementace speci´ aln´ıch ud´ alost´ı run a terminate
Ud´ alost run alokuje vstupn´ı a v´ ystupn´ı ud´alosti hradel A a B a pl´anuje poˇc´ateˇcn´ı ud´alosti popisuj´ıc´ı chov´ an´ı vstupn´ıch sign´al˚ u. D´ale pl´anuje ud´alost terminate na simulaˇcn´ı ˇcas
´ ´I KAPITOLA 5. TESTOVAN
26
70 – explicitn´ı ukonˇcen´ı simulace. Ud´alosti popisuj´ıc´ı vstupn´ı sign´aly a ud´alost terminate zap´ıˇse metodou set destruct do fronty alokovan´ ych objekt˚ u. Nakonec vytiskne prvn´ı ˇr´adek popisuj´ıc´ı v´ ystup u ´daj˚ u. Ud´ alost terminate vytiskne koneˇcn´ y stav vˇsech sign´al˚ u a uvoln´ı vstupn´ı a v´ ystupn´ı ud´alosti hradel A, B. V´ ysledn´ y v´ ystup simulace: TIME 0 1 3 10 10 12 13 18 19 20 20 30 35 36 38 40 42 50 51 70
I1 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1
I2 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1
I3 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 0 1 1
U 0 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0
V 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1
´ ER ˇ KAPITOLA 6. ZAV
27
6 Z´ avˇ er C´ılem pr´ ace bylo implementovat simulaˇcn´ı syst´em orientovan´ y na ud´alosti. Pˇri n´avrhu uˇzivatelsk´eho rozhran´ı jsem vych´azel ze vzorov´eho procesovˇe orientovan´eho simulaˇcn´ıho syst´emu SIMCP. Bylo tˇreba upravit p˚ uvodn´ı rozhran´ı pro pouˇzit´ı v syst´emu orientovan´em na ud´ alosti. D´ ale jsem navrhl nov´e efektivn´ı datov´e struktury. V´ ysledn´ y n´avrh jsem implementoval v jazyce C++. Bˇehem testov´an´ı jsem vytvoˇril a simuloval dva r˚ uzn´e modely re´aln´eho prostˇred´ı a tak ovˇeˇril funkˇcnost implementovan´eho simulaˇcn´ıho syst´emu. Vzorov´ y syst´em byl z d˚ uvodu pouˇzit´ı funkc´ı windows ve tˇr´ıdˇe CThread omezen pouze na tento operaˇcn´ı syst´em. Naproti tomu je m˚ uj simulaˇcn´ı syst´em pˇreloˇziteln´ y na libovoln´em operaˇcn´ım syst´emu. Simulaˇcn´ı syst´em se mi podaˇrilo implementovat u ´spˇeˇsnˇe a tak splnit i c´ıl pr´ace.
28
´ ER ˇ KAPITOLA 6. ZAV
KAPITOLA 7. LITERATURA
29
7 Literatura [1] Simulaˇcn´ı syst´em simcp. obsaˇzen v sekci literatura na pˇriloˇzen´em cd. ˇ e vysok´e uˇcen´ı technick´e [2] doc. Ing. Jiˇr´ı Douˇsa CSc. Modelov´ an´ı na ˇc´ıslicov´ych poˇc´ıtaˇc´ıch. Cesk´ v Praze, 3th edition, 1990. in Czech.
30
KAPITOLA 7. LITERATURA
ˇ ´ PR ˇ ´IRUCKA ˇ DODATEK A. UZIVATELSK A
31
A Uˇ zivatelsk´ a pˇ r´ıruˇ cka Simulaˇcn´ı syst´em je obsaˇzen v souborech simulation.h, simulation.cpp a start.cpp na pˇriloˇzen´em cd v sekci src\simulacni system. Uˇzivatel definuje model v souborech uzivatel.h a uzivatel.cpp. Vzorov´a ˇsablona tˇechto soubor˚ u je t´eˇz v sekci src\simulacni system na pˇriloˇzen´em cd.
A.1
Uˇ zivatelsk´ e rozhran´ı
Simulaˇcn´ı syst´em umoˇzn ˇuje pouˇzit´ı pl´anovac´ıch pˇr´ıkaz˚ u, informaˇcn´ıch metod a pomocn´ ych funkc´ı pro vytvoˇren´ı simulace. A.1.1
Pl´ anovac´ı pˇ r´ıkazy
Activate(l) Pˇr´ıkaz zp˚ usob´ı napl´ anov´an´ı ud´alosti na aktu´aln´ı hodnotu modelov´eho ˇcasu. Parametr l ud´ av´ a, o kterou ud´ alost se jedn´a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´ azev metody. ActivatePrior(l) Pˇr´ıkaz zp˚ usob´ı prioritn´ı napl´anov´an´ı ud´alosti na aktu´aln´ı hodnotu modelov´eho ˇcasu. Prioritn´ı pl´ anov´ an´ı znamen´a, ˇze ud´alost se napl´anuje pˇred vˇsechny ud´alosti, kter´e jsou napl´ anovan´e pro tuto hodnotu modelov´eho ˇcasu. Parametr l ud´av´a, o kterou ud´alost se jedn´ a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´azev metody. ActivateAt(t, l) Pˇr´ıkaz zp˚ usob´ı napl´anov´an´ı ud´alosti na dobu time. Pokud bude zadan´ y ˇcas menˇs´ı, neˇz aktu´ aln´ı hodnota modelov´eho ˇcasu, pˇr´ıkaz se projev´ı jako pˇr´ıkaz Activate. Parametr l ud´ av´ a, o kterou ud´alost se jedn´a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´ azev metody. ActivateAtPrior(t, l) Pˇr´ıkaz zp˚ usob´ı prioritn´ı napl´anov´an´ı ud´alosti na dobu time. Prioritn´ı pl´anov´ an´ı znamen´ a, ˇze ud´ alost se napl´anuje pˇred vˇsechny ud´alosti, kter´e jsou napl´anovan´e pro tuto hodnotu modelov´eho ˇcasu. Pokud bude ˇcas zadan´ y parametrem t, neˇz aktu´ aln´ı hodnota modelov´eho ˇcasu, pˇr´ıkaz se projev´ı jako pˇr´ıkaz ActivatePrior. Parametr l ud´ av´ a, o kterou ud´ alost se jedn´ a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´azev metody. ActivateDelay(t, l) Pˇr´ıkaz zp˚ usob´ı napl´anov´an´ı ud´alosti na dobu time+delay. Time je aktu´ aln´ı hodnota modelov´eho ˇcasu. Parametr l ud´av´a, o kterou ud´alost se jedn´a. Mus´ı b´ yt zad´ an ve tvaru n´ azev tˇr´ıdy::n´ azev metody. ActivateDelayPrior(t, l) Pˇr´ıkaz zp˚ usob´ı prioritn´ı napl´anov´an´ı ud´alosti na dobu time+delay. Time je aktu´ aln´ı hodnota modelov´eho ˇcasu. Prioritn´ı pl´anov´an´ı znamen´a, ˇze ud´alost se napl´ anuje pˇred vˇsechny ud´ alosti, kter´e jsou napl´anovan´e pro tuto hodnotu modelov´eho ˇcasu. Parametr l ud´ av´ a, o kterou ud´alost se jedn´a. Mus´ı b´ yt zad´an ve tvaru n´ azev tˇr´ıdy::n´ azev metody. ActivateBefore(e, l) Pˇr´ıkaz napl´ anuje ud´alost pˇred referenˇcn´ı ud´alost e. Parametr l ud´ av´ a, o kterou ud´ alost se jedn´ a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´azev metody. ActivateAfter(e, l) Pˇr´ıkaz napl´ anuje ud´alost za referenˇcn´ı ud´alost e. Parametr l ud´av´ a, o kterou ud´ alost se jedn´ a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´azev metody. Reactivate(l) Pˇr´ıkaz zp˚ usob´ı pˇrepl´anov´an´ı ud´alosti na aktu´aln´ı hodnotu modelov´eho ˇcasu. Parametr l ud´ av´ a, o kterou ud´alost se jedn´a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´ azev metody.
ˇ ´ PR ˇ ´IRUCKA ˇ DODATEK A. UZIVATELSK A
32
ReactivatePrior(l) Pˇr´ıkaz zp˚ usob´ı prioritn´ı pˇrepl´anov´an´ı ud´alosti na aktu´aln´ı hodnotu modelov´eho ˇcasu. Prioritn´ı pl´ anov´ an´ı znamen´a, ˇze ud´alost se napl´anuje pˇred vˇsechny ud´alosti, kter´e jsou napl´ anovan´e pro tuto hodnotu modelov´eho ˇcasu. Parametr l ud´av´a, o kterou ud´alost se jedn´ a. Mus´ı b´ yt zad´ an ve tvaru n´azev tˇr´ıdy::n´azev metody. ReactivateAt(t, l) Pˇr´ıkaz zp˚ usob´ı pˇrepl´anov´an´ı ud´alosti na dobu time. Pokud bude zadan´ y ˇcas menˇs´ı, neˇz aktu´ aln´ı hodnota modelov´eho ˇcasu, pˇr´ıkaz se projev´ı jako pˇr´ıkaz Reactivate. Parametr l ud´ av´ a, o kterou ud´ alost se jedn´a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´azev metody. ReactivateAtPrior(t, l) Pˇr´ıkaz zp˚ usob´ı prioritn´ı pˇrepl´anov´an´ı ud´alosti na dobu time. Prioritn´ı pl´anov´ an´ı znamen´ a, ˇze ud´ alost se napl´anuje pˇred vˇsechny ud´alosti, kter´e jsou napl´anovan´e pro tuto hodnotu modelov´eho ˇcasu. Pokud bude ˇcas zadan´ y parametrem t, neˇz aktu´ aln´ı hodnota modelov´eho ˇcasu, pˇr´ıkaz se projev´ı jako pˇr´ıkaz ReactivatePrior. Parametr l ud´ av´ a, o kterou ud´ alost se jedn´a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´azev metody. ReactivateDelay(t, l) Pˇr´ıkaz zp˚ usob´ı pˇrepl´anov´an´ı ud´alosti na dobu time+delay. Time je aktu´aln´ı hodnota modelov´eho ˇcasu. Parametr l ud´av´a, o kterou ud´alost se jedn´a. Mus´ı b´ yt zad´an ve tvaru n´ azev tˇr´ıdy::n´ azev metody. ReactivateDelayPrior(t, l) Pˇr´ıkaz zp˚ usob´ı prioritn´ı pˇrepl´anov´an´ı ud´alosti na dobu time+delay. Time je aktu´ aln´ı hodnota modelov´eho ˇcasu. Prioritn´ı pl´anov´an´ı znamen´a, ˇze ud´alost se napl´anuje pˇred vˇsechny ud´ alosti, kter´e jsou napl´anovan´e pro tuto hodnotu modelov´eho ˇcasu. Parametr l ud´ av´ a, o kterou ud´alost se jedn´a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´azev metody. ReactivateBefore(e, l) Pˇr´ıkaz pˇrepl´ anuje ud´alost pˇred referenˇcn´ı ud´alost e. Parametr l ud´av´a, o kterou ud´ alost se jedn´ a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´azev metody. ReactivateAfter(e, l) Pˇr´ıkaz pˇrepl´ anuje ud´alost za referenˇcn´ı ud´alost e. Parametr l ud´av´a, o kterou ud´ alost se jedn´ a. Mus´ı b´ yt zad´an ve tvaru n´azev tˇr´ıdy::n´azev metody. A.1.2
Informaˇ cn´ı metody
unsigned int get time()const Metoda vrac´ı hodnotu modelov´eho ˇcasu, na kterou je ud´alost napl´anovan´ a. unsigned int get id()const Metoda vrac´ı identifikaci ud´alosti. bool idle()const Metoda vrac´ı true, pokud je ud´alost pasivn´ı. A.1.3
Pomocn´ e funkce
const event *current()const Funkce vrac´ı konstantn´ı ukazatel na aktivn´ı ud´alost. static unsigned int real time() Funkce vrac´ı aktu´aln´ı hodnotu simulaˇcn´ıho ˇcasu. void set destruct(event *obj) Funkce zaznamen´a ud´alost obj do seznamu alokovan´ ych ud´alost´ı. (Ud´ alost bude automaticky uvolnˇena po skonˇcen´ı simulace.)
ˇ ´ PR ˇ ´IRUCKA ˇ DODATEK A. UZIVATELSK A
A.2
33
Instalace
Simulaˇcn´ı syst´em lze pouˇz´ıt na libovoln´em poˇc´ıtaˇci, kter´ y obsahuje pˇrekladaˇc z jazyka C++, potˇrebn´ y v´ ypoˇcetn´ı v´ ykon z´ avis´ı na n´aroˇcnosti uˇzivatelem vytvoˇren´e simulace. Pro zprovoznˇen´ı zkop´ırujte obsah adres´aˇre src\simulacni system do sv´eho pracovn´ıho adres´ aˇre a editujte soubory uzivatel.cpp a uzivatel.h. Mus´ı b´ yt naˇctena knihovna simulaˇcn´ıho syst´emu (direktiva preprocesoru #include ”simulation.h”). D´ ale mus´ı b´ yt definov´ ana poˇc´ateˇcn´ı ud´alost run. Vˇsechny tˇr´ıdy definuj´ıc´ı ud´alosti mus´ı dˇedit tˇr´ıdu event, ale n´ azvy tˇechto tˇr´ıd a vlastn´ıch ud´alost´ı mohou b´ yt libovoln´e. Nakonec soubory pˇreloˇzte pˇrekladaˇcem z jazyka C++. V´ ysledn´e zdrojov´e k´ody lze pˇreloˇzit na libovoln´em operaˇcn´ım syst´emu, napˇr´ıklad v solarisu nebo linuxu pomoc´ı pˇr´ıkazu: g++ simulation.cpp start.cpp uzivatel.cpp. Pro pouˇzit´ı ve v´ yvojov´em prostˇred´ı vytvoˇrte nov´ y projekt a pˇridejte do nˇej soubory zkop´ırovan´e do pracovn´ıho adres´ aˇre. Editujte soubory uzivatel.h a uzivatel.cpp a nakonec projekt spust’te pˇr´ıkazem v´ yvojov´eho prostˇred´ı run.
34
ˇ ´ PR ˇ ´IRUCKA ˇ DODATEK A. UZIVATELSK A
ˇ ˇ EHO ´ DODATEK B. OBSAH PRILO ZEN CD
35
B Obsah pˇ riloˇ zen´ eho CD ´ • index.html Uvodn´ ı soubor, obsahuje abstrakt, podrobn´ y obsah pˇriloˇzen´eho cd a uˇzivatelskou pˇr´ıruˇcku. • exe Adres´ aˇr, obsahuje spustiteln´e simulace. – windows – verze pro operaˇcn´ı syst´em windows – solaris – verze pro operaˇcn´ı syst´em solaris – linux – verze pro operaˇcn´ı syst´em linux • literatura Adres´ aˇr, obsahuje vzorov´ y simulaˇcn´ı syst´em SIMCP. • src Adres´ aˇr, obsahuje zdrojov´e k´ody simulaˇcn´ıho syst´emu a hotov´ ych model˚ u. – simulacni system – adres´aˇr, obsahuje zdrojov´e soubory simulaˇcn´ıho syst´emu: simulation.h, simulation.cpp, start.cpp a ˇsablonu pro uˇzivatelsk´e simulace uzivatel.h a uzivatel.cpp. – modely – adres´ aˇr, obsahuje zdrojov´e soubory hotov´ ych simulac´ı. • text Adres´ aˇr, obsahuje text bakal´aˇrsk´e pr´ace. – pdf – adres´ aˇr, obsahuje text bakal´aˇrsk´e pr´ace ve form´atu pdf. – tex – adres´ aˇr, obsahuje zdrojov´ y text bakal´aˇrsk´e pr´ace ve form´atu tex.