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

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.15! root       13: #include "event.h"
1.1.1.3   root       14: #include "mainapp.h"
1.1.1.9   root       15: #include "mainbus.h"
1.1       root       16: #include "scheduler.h"
1.1.1.8   root       17: #include "signalthread.h"
1.1.1.9   root       18: #include "syncer.h"
1.1.1.15! root       19: #include "uimessage.h"
1.1       root       20: 
                     21: // コンストラクタ
1.1.1.11  root       22: VM::VM(const char *vmname_)
1.1       root       23: {
1.1.1.11  root       24:        vmname = vmname_;
                     25:        assert(vmname);
                     26: 
1.1.1.8   root       27:        // SignalThread は他のスレッドより先に起動する必要があるので、先頭。
1.1.1.15! root       28:        // EventManager は Scheduler に必要。
1.1.1.8   root       29:        // Scheduler は以降の他のデバイスからのイベント登録を受け付ける必要が
                     30:        // あるためその次。
1.1.1.14  root       31:        // Debugger は HostCOM と stdio ドライバが競合した場合に優先したいため
                     32:        // もあって必ず先に配置する必要がある。
1.1.1.8   root       33:        NEWDV(SignalThread, new SignalThread());
1.1.1.15! root       34:        NEWDV(EventManager, new EventManager());
1.1.1.8   root       35:        NEWDV(Scheduler, new Scheduler());
1.1.1.9   root       36:        NEWDV(Syncer, new Syncer());
1.1.1.8   root       37:        NEWDV(Debugger, new Debugger());
1.1       root       38: }
                     39: 
                     40: // デストラクタ
                     41: VM::~VM()
                     42: {
1.1.1.4   root       43:        Dispose();
                     44: }
                     45: 
                     46: // 終了
                     47: void
                     48: VM::Dispose()
                     49: {
1.1.1.15! root       50:        // (もう止まってるはずだが) 念のため UIMessage の送出を止める。
        !            51:        gMainApp.GetUIMessage()->StopUIMessage();
        !            52: 
        !            53:        // スレッドを止める。
1.1.1.8   root       54:        // デバッガスレッドがスケジューラスレッドにアクセスするのでデバッガが先。
                     55:        if ((bool)pDebugger) {
1.1.1.9   root       56:                GetDebugger()->TerminateThread();
1.1.1.8   root       57:        }
                     58:        if ((bool)pScheduler) {
1.1.1.9   root       59:                GetScheduler()->TerminateThread();
1.1.1.8   root       60:        }
                     61: 
                     62:        // 残りのスレッドを停止
                     63:        for (auto obj : gMainApp.GetObjects()) {
                     64:                auto th = dynamic_cast<ThreadDevice *>(obj);
                     65:                if (th) {
                     66:                        th->TerminateThread();
                     67:                }
1.1.1.4   root       68:        }
1.1.1.8   root       69: 
                     70:        // 作ったときと逆順で解放する
                     71:        if ((bool)pDebugger) {
                     72:                pDebugger.reset();
                     73:        }
                     74: 
                     75:        if ((bool)pScheduler) {
                     76:                pScheduler.reset();
                     77:        }
                     78: 
1.1.1.15! root       79:        if ((bool)pEventManager) {
        !            80:                pEventManager.reset();
        !            81:        }
        !            82: 
1.1.1.8   root       83:        // ほかのオブジェクトの解放はグローバルデストラクタにおまかせ。
                     84:        // だめだったらまた考える。
1.1       root       85: }
                     86: 
1.1.1.13  root       87: // 動的コンストラクション。
1.1       root       88: bool
1.1.1.13  root       89: VM::Create(VM::CreationPhase phase)
1.1       root       90: {
1.1.1.8   root       91:        // d->Create() は Object を追加する場合があるため、ここで
1.1.1.13  root       92:        // ranged for は使えない。また追加されたデバイスの Create()/Create2() も
1.1.1.7   root       93:        // 実行したいため、ループ終了条件で毎回 size() を取り出して比較する。
1.1.1.8   root       94:        for (int i = 0; i < gMainApp.GetObjects().size(); i++) {
                     95:                auto dev = dynamic_cast<Device *>(gMainApp.GetObjects()[i]);
                     96:                if (dev) {
1.1.1.13  root       97:                        if (phase == CreationPhase::First) {
                     98:                                if (!dev->Create()) {
                     99:                                        return false;
                    100:                                }
                    101:                        } else {
                    102:                                if (!dev->Create2()) {
                    103:                                        return false;
                    104:                                }
1.1.1.8   root      105:                        }
1.1       root      106:                }
                    107:        }
                    108: 
1.1.1.13  root      109:        // ログのためのメンバ変数初期化。
                    110:        // 同じオブジェクトに対して複数回呼んでも副作用はない。
                    111:        for (auto obj : gMainApp.GetObjects()) {
                    112:                auto dev = dynamic_cast<Device *>(obj);
                    113:                if (dev) {
                    114:                        dev->EarlyInit();
                    115:                }
                    116:        }
                    117: 
1.1.1.15! root      118:        // 名無しオブジェクトがあれば開発中に検出したい。
        !           119:        // 名無しでも動作には影響ないのでリリース版では怒られないでほしい。
        !           120: #if !defined(RELEASE)
        !           121:        for (auto obj : gMainApp.GetObjects()) {
        !           122:                if (obj->GetName().empty()) {
        !           123:                        printf("Objects:\n");
        !           124:                        for (auto o : gMainApp.GetObjects()) {
        !           125:                                printf("%s\n", o->GetName().c_str());
        !           126:                        }
        !           127:                        assert(obj->GetName().empty() == false);
        !           128:                }
        !           129:        }
        !           130: #endif
        !           131: 
1.1       root      132:        return true;
                    133: }
                    134: 
                    135: // 初期化
                    136: bool
                    137: VM::Init()
                    138: {
1.1.1.8   root      139:        for (auto obj : gMainApp.GetObjects()) {
                    140:                auto dev = dynamic_cast<Device *>(obj);
                    141:                if (dev) {
                    142:                        if (!dev->Init()) {
                    143:                                return false;
                    144:                        }
                    145:                }
                    146:        }
                    147: 
1.1.1.11  root      148:        // デバイスの初期化が全部出来たのでメインバスの初期化。
                    149:        auto mainbus = dynamic_cast<MainbusDevice*>(pMainbus.get());
                    150:        if (mainbus->InitMainbus() == false) {
                    151:                return false;
                    152:        }
                    153: 
1.1.1.12  root      154:        // イベントが出揃ったのでスケジューラモニタの行数を確定。
                    155:        auto scheduler = dynamic_cast<Scheduler*>(pScheduler.get());
                    156:        if (scheduler->Init2() == false) {
                    157:                return false;
                    158:        }
                    159: 
1.1.1.8   root      160:        return true;
                    161: }
                    162: 
                    163: // スレッド開始
                    164: bool
                    165: VM::StartThread()
                    166: {
                    167:        for (auto obj : gMainApp.GetObjects()) {
                    168:                auto th = dynamic_cast<ThreadDevice *>(obj);
                    169:                if (th) {
                    170:                        if (!th->StartThread()) {
                    171:                                return false;
                    172:                        }
1.1       root      173:                }
                    174:        }
                    175: 
                    176:        return true;
                    177: }

unix.superglobalmegacorp.com

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