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

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: 
1.1.1.13! root       74: // 動的コンストラクション。
1.1       root       75: bool
1.1.1.13! root       76: VM::Create(VM::CreationPhase phase)
1.1       root       77: {
1.1.1.8   root       78:        // d->Create() は Object を追加する場合があるため、ここで
1.1.1.13! root       79:        // ranged for は使えない。また追加されたデバイスの Create()/Create2() も
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) {
1.1.1.13! root       84:                        if (phase == CreationPhase::First) {
        !            85:                                if (!dev->Create()) {
        !            86:                                        return false;
        !            87:                                }
        !            88:                        } else {
        !            89:                                if (!dev->Create2()) {
        !            90:                                        return false;
        !            91:                                }
1.1.1.8   root       92:                        }
1.1       root       93:                }
                     94:        }
                     95: 
1.1.1.13! root       96:        // ログのためのメンバ変数初期化。
        !            97:        // 同じオブジェクトに対して複数回呼んでも副作用はない。
        !            98:        for (auto obj : gMainApp.GetObjects()) {
        !            99:                auto dev = dynamic_cast<Device *>(obj);
        !           100:                if (dev) {
        !           101:                        dev->EarlyInit();
        !           102:                }
        !           103:        }
        !           104: 
1.1       root      105:        return true;
                    106: }
                    107: 
                    108: // 初期化
                    109: bool
                    110: VM::Init()
                    111: {
1.1.1.8   root      112:        for (auto obj : gMainApp.GetObjects()) {
                    113:                auto dev = dynamic_cast<Device *>(obj);
                    114:                if (dev) {
                    115:                        if (!dev->Init()) {
                    116:                                return false;
                    117:                        }
                    118:                }
                    119:        }
                    120: 
1.1.1.11  root      121:        // デバイスの初期化が全部出来たのでメインバスの初期化。
                    122:        auto mainbus = dynamic_cast<MainbusDevice*>(pMainbus.get());
                    123:        if (mainbus->InitMainbus() == false) {
                    124:                return false;
                    125:        }
                    126: 
1.1.1.12  root      127:        // イベントが出揃ったのでスケジューラモニタの行数を確定。
                    128:        auto scheduler = dynamic_cast<Scheduler*>(pScheduler.get());
                    129:        if (scheduler->Init2() == false) {
                    130:                return false;
                    131:        }
                    132: 
1.1.1.8   root      133:        return true;
                    134: }
                    135: 
                    136: // スレッド開始
                    137: bool
                    138: VM::StartThread()
                    139: {
                    140:        for (auto obj : gMainApp.GetObjects()) {
                    141:                auto th = dynamic_cast<ThreadDevice *>(obj);
                    142:                if (th) {
                    143:                        if (!th->StartThread()) {
                    144:                                return false;
                    145:                        }
1.1       root      146:                }
                    147:        }
                    148: 
                    149:        return true;
                    150: }
                    151: 
                    152: // 設定の適用
                    153: bool
                    154: VM::Apply()
                    155: {
1.1.1.8   root      156:        for (auto obj : gMainApp.GetObjects()) {
                    157:                auto dev = dynamic_cast<Device *>(obj);
                    158:                if (dev) {
                    159:                        if (!dev->Apply()) {
                    160:                                return false;
                    161:                        }
1.1       root      162:                }
                    163:        }
                    164: 
                    165:        return true;
                    166: }

unix.superglobalmegacorp.com

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