--- nono/vm/scheduler.h 2026/04/29 17:04:32 1.1.1.2 +++ nono/vm/scheduler.h 2026/04/29 17:04:45 1.1.1.6 @@ -1,22 +1,24 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #pragma once +#include "device.h" +#include "event.h" +#include "mpu.h" #include #include +#include #include #include -#include "device.h" -#include "event.h" -#include "mpu.h" // スケジューラ class Scheduler : public Device { - typedef Device inherited; + using inherited = Device; // リクエストフラグ static const uint REQ_SYNC = 0x0001; // スケジューラを同期モードに @@ -27,6 +29,7 @@ class Scheduler : public Device static const uint REQ_POWER_ON = 0x0010; // 電源オン static const uint REQ_POWER_OFF = 0x0020; // 電源オフ static const uint REQ_EXIT = 0x0040; // アプリケーション終了 + static const uint REQ_RESET = 0x0080; // ハードウェアリセット // 動作モード // 動作モード変数 (mode) は高速モードか通常モードかと、MPU が通常状態が @@ -34,16 +37,24 @@ class Scheduler : public Device // なら通常走行するというロジックを比較1回で済ませるため。 static const uint32 SCHED_STOP = 0x0001; // スケジューラが STOP 状態 static const uint32 SCHED_SYNC = 0x0002; // 同期(%1)/高速(%0)モード - // 演算を1回で済ませるために、同じ値にすること + + // 演算を1回で済ませるために、この2値は同じ値にすること。 + // ただしこれをチェックするために全員が m68030.h/m88100.h を include すると + // m88k を修正するたびに m68k も含めて全部ビルドが走るのはかなりつらいので + // 定義されてる時だけチェックすることにする。 + // もともと将来のポカよけなのでビルド中1回でも通過すれば十分。 +#if defined(CPU_REQ_STOP) static_assert(SCHED_STOP == CPU_REQ_STOP, "must be the same"); +#endif public: Scheduler(); - virtual ~Scheduler(); + virtual ~Scheduler() override; - virtual bool Init(); + bool Init() override; - virtual bool MonitorUpdate(); + nnSize GetMonitorSize() override; + void MonitorUpdate(TextScreen&) override; // スレッド開始 void ThreadRun(); @@ -59,20 +70,11 @@ class Scheduler : public Device atomic_reqflag |= REQ_POWER_OFF; } - // サイクル数を仮想時間 [nsec] に変換 - uint64 Cycle2Vtime(uint64 cycle) const { - return cycle * 1000 * 1000 / mpu_clock; - } - - // 仮想時間 [nsec] をサイクル数に変換 - uint64 Vtime2Cycle(uint64 vtime) const { - return vtime * mpu_clock / (1000 * 1000); + // リセット要求 + void RequestResetHard() { + atomic_reqflag |= REQ_RESET; } - // 仮想時刻取得 - uint64 GetVirtTime() const { - return Cycle2Vtime(gMPU->total_cycle()); - } // スケジューラが高速モードなら true を返す。 // ここでいう高速モードは STOP 状態中でも高速モード。 @@ -99,20 +101,21 @@ class Scheduler : public Device std::mutex cvmtx {}; private: + // リセットイベントコールバック + void ResetCallback(Event& ev); + pthread_t thread {}; - bool thread_created = false; // スレッドが作成されたら true + bool thread_created {}; // スレッドが作成されたら true // スケジューラの動作モード。SCHED_* - uint32 mode = 0; - - int mpu_clock = 0; // MPU クロック [kHz] + uint32 mode {}; - uint64 rtimestart = 0; // スケジューラ開始実時刻 - uint64 rtimebase = 0; // 実時間の基準時刻 - uint64 vtimebase = 0; // 仮想時間の基準時刻 + uint64 rtimestart {}; // スケジューラ開始実時刻 + uint64 rtimebase {}; // 実時間の基準時刻 + uint64 vtimebase {}; // 仮想時間の基準時刻 // 前回 RTC へ 32Hz 入力パルスを入れた時刻 (実時間の絶対時刻系) - uint64 rtc_last_clock = 0; + uint64 rtc_last_clock {}; }; extern std::unique_ptr gScheduler;