|
|
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: // あるためその次。
1.1.1.14! root 28: // Debugger は HostCOM と stdio ドライバが競合した場合に優先したいため
! 29: // もあって必ず先に配置する必要がある。
1.1.1.8 root 30: NEWDV(SignalThread, new SignalThread());
31: NEWDV(Scheduler, new Scheduler());
1.1.1.9 root 32: NEWDV(Syncer, new Syncer());
1.1.1.8 root 33: NEWDV(Debugger, new Debugger());
1.1 root 34: }
35:
36: // デストラクタ
37: VM::~VM()
38: {
1.1.1.4 root 39: Dispose();
40: }
41:
42: // 終了
43: void
44: VM::Dispose()
45: {
1.1.1.8 root 46: // まずスレッドを止める。
47: // デバッガスレッドがスケジューラスレッドにアクセスするのでデバッガが先。
48: if ((bool)pDebugger) {
1.1.1.9 root 49: GetDebugger()->TerminateThread();
1.1.1.8 root 50: }
51: if ((bool)pScheduler) {
1.1.1.9 root 52: GetScheduler()->TerminateThread();
1.1.1.8 root 53: }
54:
55: // 残りのスレッドを停止
56: for (auto obj : gMainApp.GetObjects()) {
57: auto th = dynamic_cast<ThreadDevice *>(obj);
58: if (th) {
59: th->TerminateThread();
60: }
1.1.1.4 root 61: }
1.1.1.8 root 62:
63: // 作ったときと逆順で解放する
64: if ((bool)pDebugger) {
65: pDebugger.reset();
66: }
67:
68: if ((bool)pScheduler) {
69: pScheduler.reset();
70: }
71:
72: // ほかのオブジェクトの解放はグローバルデストラクタにおまかせ。
73: // だめだったらまた考える。
1.1 root 74: }
75:
1.1.1.13 root 76: // 動的コンストラクション。
1.1 root 77: bool
1.1.1.13 root 78: VM::Create(VM::CreationPhase phase)
1.1 root 79: {
1.1.1.8 root 80: // d->Create() は Object を追加する場合があるため、ここで
1.1.1.13 root 81: // ranged for は使えない。また追加されたデバイスの Create()/Create2() も
1.1.1.7 root 82: // 実行したいため、ループ終了条件で毎回 size() を取り出して比較する。
1.1.1.8 root 83: for (int i = 0; i < gMainApp.GetObjects().size(); i++) {
84: auto dev = dynamic_cast<Device *>(gMainApp.GetObjects()[i]);
85: if (dev) {
1.1.1.13 root 86: if (phase == CreationPhase::First) {
87: if (!dev->Create()) {
88: return false;
89: }
90: } else {
91: if (!dev->Create2()) {
92: return false;
93: }
1.1.1.8 root 94: }
1.1 root 95: }
96: }
97:
1.1.1.13 root 98: // ログのためのメンバ変数初期化。
99: // 同じオブジェクトに対して複数回呼んでも副作用はない。
100: for (auto obj : gMainApp.GetObjects()) {
101: auto dev = dynamic_cast<Device *>(obj);
102: if (dev) {
103: dev->EarlyInit();
104: }
105: }
106:
1.1 root 107: return true;
108: }
109:
110: // 初期化
111: bool
112: VM::Init()
113: {
1.1.1.8 root 114: for (auto obj : gMainApp.GetObjects()) {
115: auto dev = dynamic_cast<Device *>(obj);
116: if (dev) {
117: if (!dev->Init()) {
118: return false;
119: }
120: }
121: }
122:
1.1.1.11 root 123: // デバイスの初期化が全部出来たのでメインバスの初期化。
124: auto mainbus = dynamic_cast<MainbusDevice*>(pMainbus.get());
125: if (mainbus->InitMainbus() == false) {
126: return false;
127: }
128:
1.1.1.12 root 129: // イベントが出揃ったのでスケジューラモニタの行数を確定。
130: auto scheduler = dynamic_cast<Scheduler*>(pScheduler.get());
131: if (scheduler->Init2() == false) {
132: return false;
133: }
134:
1.1.1.8 root 135: return true;
136: }
137:
138: // スレッド開始
139: bool
140: VM::StartThread()
141: {
142: for (auto obj : gMainApp.GetObjects()) {
143: auto th = dynamic_cast<ThreadDevice *>(obj);
144: if (th) {
145: if (!th->StartThread()) {
146: return false;
147: }
1.1 root 148: }
149: }
150:
151: return true;
152: }
153:
154: // 設定の適用
155: bool
156: VM::Apply()
157: {
1.1.1.8 root 158: for (auto obj : gMainApp.GetObjects()) {
159: auto dev = dynamic_cast<Device *>(obj);
160: if (dev) {
161: if (!dev->Apply()) {
162: return false;
163: }
1.1 root 164: }
165: }
166:
167: return true;
168: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.