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

unix.superglobalmegacorp.com

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