Annotation of nono/vm/syncer.h, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2020 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: //
        !             8: // 実時間同期
        !             9: //
        !            10: 
        !            11: #pragma once
        !            12: 
        !            13: #include "event.h"
        !            14: #include "fixedqueue.h"
        !            15: #include "message.h"
        !            16: #include "monitor.h"
        !            17: #include "stopwatch.h"
        !            18: 
        !            19: class MainbusDevice;
        !            20: class MainRAMDevice;
        !            21: 
        !            22: class Syncer : public Device
        !            23: {
        !            24:        using inherited = Device;
        !            25: 
        !            26:  public:
        !            27:        // 動作モード
        !            28:        // 動作モード変数 (mode) はスケジューラの走行状態を表している。以下の
        !            29:        // ビットがすべて %0 なら高速モード、どれかでも %1 なら通常モードになる。
        !            30:        //
        !            31:        //      | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
        !            32:        // mode |         |POFF|KEY |BOOT|SYNC| CPUSTAT |
        !            33:        //                  |    |    |    |     +---+---- CPU の状態
        !            34:        //                  |    |    |    +-------------- 高速モード抑制
        !            35:        //                  |    |    +------------------- ブートページ実行中
        !            36:        //                  |    +------------------------ キー入力中
        !            37:        //                  +----------------------------- 電源オフ
        !            38:        //
        !            39:        // bit1,0 (CPUSTAT) は CPU の状態を示す。%00 の時だけ高速走行が可能。
        !            40:        // これは RequestCPUMode() の引数で指定する。
        !            41:        //   b1 b0
        !            42:        //    0  0  通常状態
        !            43:        //    0  1  STOP 状態 (m88k なら擬似 STOP 状態)
        !            44:        //    1  0  HALT 状態 (ダブルバスフォールト)
        !            45:        //    1  1  HALT 状態だがこちらのビットパターンは使わない
        !            46: 
        !            47:        static const uint32 SCHED_CPU_STOP      = 0x0001;       // CPU が STOP 状態
        !            48:        static const uint32 SCHED_CPU_HALT      = 0x0002;       // CPU が HALT 状態
        !            49:        static const uint32 SCHED_SYNC          = 0x0004;       // 高速モード抑制指示(UI)
        !            50:        static const uint32 SCHED_BOOT          = 0x0008;       // ブートページ実行中
        !            51:        static const uint32 SCHED_KEY           = 0x0010;       // キー入力中
        !            52:        static const uint32 SCHED_POWEROFF      = 0x0020;       // 電源オフ
        !            53: 
        !            54:        // 便宜上用意しておく
        !            55:        static const uint32 SCHED_CPU_NORMAL= 0x0000;   // CPU が通常状態
        !            56:        static const uint32 SCHED_CPU_MASK = (SCHED_CPU_STOP | SCHED_CPU_HALT);
        !            57: 
        !            58:  public:
        !            59:        Syncer();
        !            60:        ~Syncer() override;
        !            61: 
        !            62:        bool Init() override;
        !            63: 
        !            64:        void StartTime();                       // 時間の始まり
        !            65: 
        !            66:        void StartRealTime();           // 実時間を再開
        !            67:        void StopRealTime();            // 実時間を停止
        !            68: 
        !            69:        uint64 GetRealTime() const { return rtime; }
        !            70: 
        !            71:        // 現在の実行モードを返す。
        !            72:        uint32 GetRunMode() const { return mode; }
        !            73: 
        !            74:        // CPU 状態変更を指示する。
        !            75:        void RequestCPUMode(uint32 mode_);
        !            76: 
        !            77:        // 高速モード(UIによる指示)なら true を返す。
        !            78:        // ここでいう高速モードは STOP 状態中でも高速モード。
        !            79:        bool GetFullSpeed() const { return ((mode & SCHED_SYNC) == 0); }
        !            80: 
        !            81:        // 高速モードを指示する。
        !            82:        // true なら高速モード、false なら同期モード。
        !            83:        void RequestFullSpeed(bool enable);
        !            84: 
        !            85:        // ブートページモードの変更を指示する。
        !            86:        void RequestBootPageMode(bool isrom);
        !            87: 
        !            88:        // キー入力状態の変更を指示する。
        !            89:        void RequestKeyPressed(bool pressed);
        !            90: 
        !            91:        // 電源オフの状態の変更を指示する。オフになったとき true。
        !            92:        void RequestPowerOffMode(bool poweroff);
        !            93: 
        !            94:        // パフォーマンス測定用に実時間をログ出力
        !            95:        void PutlogRealtime();
        !            96: 
        !            97:        // パフォーマンスカウンタの値取得 (UI 表示用)
        !            98:        int GetPerfCounter() const { return perf_counter; }
        !            99: 
        !           100:        // モニタ更新の下請け
        !           101:        int MonitorUpdateSub(TextScreen& screen, uint64 vtime);
        !           102: 
        !           103:  private:
        !           104:        void ChangeMode(uint32 newmode);
        !           105: 
        !           106:        // 同期イベント
        !           107:        void SyncCallback(Event& ev);
        !           108: 
        !           109:        // 動作モード変更メッセージ
        !           110:        void ChangeModeCallback(MessageID, uint32);
        !           111: 
        !           112:        // 同期処理
        !           113:        void DoSync();
        !           114: 
        !           115:        void CalcPerf();
        !           116: 
        !           117:        // スケジューラの動作モード。SCHED_*
        !           118:        uint32 mode {};
        !           119: 
        !           120:        // 実時間の基準となるストップウォッチ
        !           121:        Stopwatch realtime {};
        !           122: 
        !           123:        // 同期した時点の実経過時間
        !           124:        uint64 rtime {};
        !           125: 
        !           126:        // 同期調整用
        !           127:        uint64 rtime_epoch {};
        !           128:        uint64 vtime_epoch {};
        !           129: 
        !           130:        // sleep しすぎた時間の最大値
        !           131:        uint64 overslept {};
        !           132: 
        !           133:        // 同期回数
        !           134:        uint sync_count {};                     // 現在の1秒間での同期回数
        !           135:        uint last_sync_count {};        // 前回の1秒間での同期回数
        !           136: 
        !           137:        // パフォーマンスカウンタ
        !           138:        // perfq が移動平均用のバッファ。四捨五入用に10倍値を持っておく
        !           139:        // (100% なら 1000)。perf_counter は perfq から求めた実行率で
        !           140:        // 小数以下を四捨五入する (のでこっちは 100% なら 100)。
        !           141:        int perf_counter {};                    // 実行率 [%]
        !           142:        FixedQueue<uint32, 3> perfq {}; // 移動平均用のバッファ
        !           143:        uint64 next_perf_rtime {};              // 次回測定予定の実経過時間
        !           144:        uint64 last_perf_rtime {};              // 前回測定時の実経過時間
        !           145:        uint64 last_perf_vtime {};              // 前回測定時の仮想経過時間
        !           146: 
        !           147:        MainbusDevice *mainbus {};
        !           148:        MainRAMDevice *mainram {};
        !           149: 
        !           150:        // 同期イベント
        !           151:        Event sync_event { this };
        !           152: };
        !           153: 
        !           154: static inline Syncer *GetSyncer() {
        !           155:        return Object::GetObject<Syncer>(OBJ_SYNCER);
        !           156: }

unix.superglobalmegacorp.com

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