|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.