Annotation of nono/vm/vm.cpp, revision 1.1.1.12

1.1       root        1: //
                      2: // nono
1.1.1.4   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.8   root        7: //
                      8: // VM (基本クラス)
                      9: //
                     10: 
1.1       root       11: #include "vm.h"
1.1.1.9   root       12: #include "debugger.h"
1.1.1.3   root       13: #include "mainapp.h"
1.1.1.9   root       14: #include "mainbus.h"
1.1       root       15: #include "scheduler.h"
1.1.1.8   root       16: #include "signalthread.h"
1.1.1.9   root       17: #include "syncer.h"
1.1       root       18: 
                     19: // コンストラクタ
1.1.1.11  root       20: VM::VM(const char *vmname_)
1.1       root       21: {
1.1.1.11  root       22:        vmname = vmname_;
                     23:        assert(vmname);
                     24: 
1.1.1.8   root       25:        // SignalThread は他のスレッドより先に起動する必要があるので、先頭。
                     26:        // Scheduler は以降の他のデバイスからのイベント登録を受け付ける必要が
                     27:        // あるためその次。
                     28:        NEWDV(SignalThread, new SignalThread());
                     29:        NEWDV(Scheduler, new Scheduler());
1.1.1.9   root       30:        NEWDV(Syncer, new Syncer());
1.1.1.8   root       31:        NEWDV(Debugger, new Debugger());
1.1       root       32: }
                     33: 
                     34: // デストラクタ
                     35: VM::~VM()
                     36: {
1.1.1.4   root       37:        Dispose();
                     38: }
                     39: 
                     40: // 終了
                     41: void
                     42: VM::Dispose()
                     43: {
1.1.1.8   root       44:        // まずスレッドを止める。
                     45:        // デバッガスレッドがスケジューラスレッドにアクセスするのでデバッガが先。
                     46:        if ((bool)pDebugger) {
1.1.1.9   root       47:                GetDebugger()->TerminateThread();
1.1.1.8   root       48:        }
                     49:        if ((bool)pScheduler) {
1.1.1.9   root       50:                GetScheduler()->TerminateThread();
1.1.1.8   root       51:        }
                     52: 
                     53:        // 残りのスレッドを停止
                     54:        for (auto obj : gMainApp.GetObjects()) {
                     55:                auto th = dynamic_cast<ThreadDevice *>(obj);
                     56:                if (th) {
                     57:                        th->TerminateThread();
                     58:                }
1.1.1.4   root       59:        }
1.1.1.8   root       60: 
                     61:        // 作ったときと逆順で解放する
                     62:        if ((bool)pDebugger) {
                     63:                pDebugger.reset();
                     64:        }
                     65: 
                     66:        if ((bool)pScheduler) {
                     67:                pScheduler.reset();
                     68:        }
                     69: 
                     70:        // ほかのオブジェクトの解放はグローバルデストラクタにおまかせ。
                     71:        // だめだったらまた考える。
1.1       root       72: }
                     73: 
                     74: // コンストラクタ後の初期化
                     75: bool
                     76: VM::Create()
                     77: {
1.1.1.8   root       78:        // d->Create() は Object を追加する場合があるため、ここで
1.1.1.10  root       79:        // ranged for は使えない。また追加されたデバイスの Create() も
1.1.1.7   root       80:        // 実行したいため、ループ終了条件で毎回 size() を取り出して比較する。
1.1.1.8   root       81:        for (int i = 0; i < gMainApp.GetObjects().size(); i++) {
                     82:                auto dev = dynamic_cast<Device *>(gMainApp.GetObjects()[i]);
                     83:                if (dev) {
                     84:                        if (!dev->Create()) {
                     85:                                return false;
                     86:                        }
1.1       root       87:                }
                     88:        }
                     89: 
                     90:        return true;
                     91: }
                     92: 
                     93: // 初期化
                     94: bool
                     95: VM::Init()
                     96: {
1.1.1.8   root       97:        for (auto obj : gMainApp.GetObjects()) {
                     98:                auto dev = dynamic_cast<Device *>(obj);
                     99:                if (dev) {
                    100:                        if (!dev->Init()) {
                    101:                                return false;
                    102:                        }
                    103:                }
                    104:        }
                    105: 
1.1.1.11  root      106:        // デバイスの初期化が全部出来たのでメインバスの初期化。
                    107:        auto mainbus = dynamic_cast<MainbusDevice*>(pMainbus.get());
                    108:        if (mainbus->InitMainbus() == false) {
                    109:                return false;
                    110:        }
                    111: 
1.1.1.12! root      112:        // イベントが出揃ったのでスケジューラモニタの行数を確定。
        !           113:        auto scheduler = dynamic_cast<Scheduler*>(pScheduler.get());
        !           114:        if (scheduler->Init2() == false) {
        !           115:                return false;
        !           116:        }
        !           117: 
1.1.1.8   root      118:        return true;
                    119: }
                    120: 
                    121: // スレッド開始
                    122: bool
                    123: VM::StartThread()
                    124: {
                    125:        for (auto obj : gMainApp.GetObjects()) {
                    126:                auto th = dynamic_cast<ThreadDevice *>(obj);
                    127:                if (th) {
                    128:                        if (!th->StartThread()) {
                    129:                                return false;
                    130:                        }
1.1       root      131:                }
                    132:        }
                    133: 
                    134:        return true;
                    135: }
                    136: 
                    137: // 設定の適用
                    138: bool
                    139: VM::Apply()
                    140: {
1.1.1.8   root      141:        for (auto obj : gMainApp.GetObjects()) {
                    142:                auto dev = dynamic_cast<Device *>(obj);
                    143:                if (dev) {
                    144:                        if (!dev->Apply()) {
                    145:                                return false;
                    146:                        }
1.1       root      147:                }
                    148:        }
                    149: 
                    150:        return true;
                    151: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.