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

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 "fixedqueue.h"
                     14: #include "message.h"
                     15: #include "stopwatch.h"
                     16: 
1.1.1.3   root       17: class MPU680x0Device;
1.1.1.8   root       18: class ThreadManager;
1.1.1.3   root       19: 
1.1       root       20: class Syncer : public Device
                     21: {
                     22:        using inherited = Device;
                     23: 
                     24:  public:
                     25:        // 動作モード
                     26:        // 動作モード変数 (mode) はスケジューラの走行状態を表している。以下の
                     27:        // ビットがすべて %0 なら高速モード、どれかでも %1 なら通常モードになる。
                     28:        //
                     29:        //      | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
1.1.1.8   root       30:        // mode |         |SND |POFF|KEY |SYNC|HALT|IDLE|
                     31:        //                  |    |    |    |    |    +---- CPU & DMAC アイドル
                     32:        //                  |    |    |    |    +--------- CPU HALT
                     33:        //                  |    |    |    +-------------- 高速モード抑制
                     34:        //                  |    |    +------------------- キー入力中
                     35:        //                  |    +------------------------ 電源オフ
                     36:        //                  +----------------------------- サウンド再生中
1.1       root       37:        //
1.1.1.5   root       38:        // bit1,0 は CPU から来るが、このうち bit0 だけ DMAC からのアイドル
                     39:        // ビットとの積(AND) になっているので、mode 中の bit0 は CPU も DMAC も
                     40:        // ともにアイドルの時だけ 1 になる。
                     41:        //
                     42:        // CPU  HALT (bit1) ----------------------> HALT (bit1)
                     43:        // CPU  STOP (bit0) -----------------|&
                     44:        //                                   |&---> IDLE (bit0)
                     45:        // DMAC Active ---|>--- DMAC Idle ---|&
                     46: 
                     47:        static const uint32 SYNCMODE_IDLE               = 0x0001;       // CPU & DMAC アイドル
                     48:        static const uint32 SYNCMODE_CPU_HALT   = 0x0002;       // CPU が HALT 状態
                     49:        static const uint32 SYNCMODE_SYNC               = 0x0004;       // 等速モード指示(UI)
1.1.1.7   root       50:        static const uint32 SYNCMODE_KEY                = 0x0008;       // キー入力中
                     51:        static const uint32 SYNCMODE_POWEROFF   = 0x0010;       // 電源オフ
1.1.1.8   root       52:        static const uint32 SYNCMODE_SOUND              = 0x0020;       // サウンド再生中
1.1       root       53: 
                     54:        // 便宜上用意しておく
1.1.1.5   root       55:        static const uint32 SYNCMODE_CPU_NORMAL = 0x0000;       // CPU が通常状態
                     56:        static const uint32 SYNCMODE_CPU_STOP   = 0x0001;       // CPU が STOP 状態
                     57:        static const uint32 SYNCMODE_CPU_MASK   = 0x0003;       // (HALT|STOP)
1.1       root       58: 
                     59:  public:
                     60:        Syncer();
                     61:        ~Syncer() override;
                     62: 
                     63:        bool Init() override;
                     64: 
1.1.1.6   root       65:        // 実時間系デバイスの時間軸を実時間に追従する場合は true を返す。
                     66:        bool GetSyncRealtime() const noexcept { return sync_realtime; }
                     67: 
1.1       root       68:        void StartTime();                       // 時間の始まり
                     69: 
                     70:        void StartRealTime();           // 実時間を再開
                     71:        void StopRealTime();            // 実時間を停止
                     72: 
                     73:        uint64 GetRealTime() const { return rtime; }
                     74: 
                     75:        // 現在の実行モードを返す。
                     76:        uint32 GetRunMode() const { return mode; }
                     77: 
                     78:        // CPU 状態変更を指示する。
1.1.1.8   root       79:        void NotifyCPUMode(uint32 mode_);
1.1       root       80: 
1.1.1.5   root       81:        // DMAC のアクティブ状態を指示する。
1.1.1.8   root       82:        void NotifyDMACActive(bool active);
1.1.1.5   root       83: 
1.1       root       84:        // 高速モード(UIによる指示)なら true を返す。
                     85:        // ここでいう高速モードは STOP 状態中でも高速モード。
1.1.1.5   root       86:        bool GetFullSpeed() const { return ((mode & SYNCMODE_SYNC) == 0); }
1.1       root       87: 
                     88:        // 高速モードを指示する。
                     89:        // true なら高速モード、false なら同期モード。
1.1.1.8   root       90:        void NotifyFullSpeed(bool enable);
1.1       root       91: 
                     92:        // キー入力状態の変更を指示する。
1.1.1.8   root       93:        void NotifyKeyPressed(bool pressed);
1.1       root       94: 
                     95:        // 電源オフの状態の変更を指示する。オフになったとき true。
1.1.1.8   root       96:        void NotifyPowerOffMode(bool poweroff);
                     97: 
                     98:        // サウンド出力状態の変更を指示するう。
                     99:        void NotifySoundRunning(bool running);
1.1       root      100: 
                    101:        // パフォーマンス測定用に実時間をログ出力
                    102:        void PutlogRealtime();
                    103: 
                    104:        // パフォーマンスカウンタの値取得 (UI 表示用)
1.1.1.3   root      105:        uint GetPerfCounter() const { return perf_counter; }
1.1       root      106: 
                    107:        // モニタ更新の下請け
1.1.1.9 ! root      108:        int MonitorScreenSub(TextScreen& screen, uint64 vtime);
1.1       root      109: 
                    110:  private:
                    111:        void ChangeMode(uint32 newmode);
                    112: 
                    113:        // 同期イベント
1.1.1.7   root      114:        void SyncCallback(Event *);
1.1       root      115: 
                    116:        // 動作モード変更メッセージ
1.1.1.2   root      117:        void ChangeModeMessage(MessageID, uint32);
1.1       root      118: 
                    119:        // 同期処理
                    120:        void DoSync();
                    121: 
                    122:        void CalcPerf();
                    123: 
1.1.1.6   root      124:        // 実時間系デバイスの時間軸を実時間に追従する場合は true。
                    125:        bool sync_realtime {};
                    126: 
1.1.1.5   root      127:        // スケジューラの動作モード。SYNCMODE_*
1.1       root      128:        uint32 mode {};
                    129: 
1.1.1.5   root      130:        uint32 halt {};                 // CPU が HALT なら SYNCMODE_CPU_HALT
                    131:        uint32 cpu_idle {};             // CPU が STOP なら SYNCMODE_CPU_STOP
                    132:        uint32 dmac_idle {};    // DMAC がアイドルなら SYNCMODE_IDLE
                    133: 
1.1       root      134:        // 実時間の基準となるストップウォッチ
                    135:        Stopwatch realtime {};
                    136: 
                    137:        // 同期した時点の実経過時間
                    138:        uint64 rtime {};
                    139: 
                    140:        // 同期調整用
                    141:        uint64 rtime_epoch {};
                    142:        uint64 vtime_epoch {};
                    143: 
                    144:        // sleep しすぎた時間の最大値
                    145:        uint64 overslept {};
                    146: 
                    147:        // 同期回数
                    148:        uint sync_count {};                     // 現在の1秒間での同期回数
                    149:        uint last_sync_count {};        // 前回の1秒間での同期回数
                    150: 
1.1.1.9 ! root      151:        uint64 last_mpu_exec {};
        !           152:        uint64 last_mpu_exec_per_sec {};
        !           153: 
1.1       root      154:        // パフォーマンスカウンタ
                    155:        // perfq が移動平均用のバッファ。四捨五入用に10倍値を持っておく
                    156:        // (100% なら 1000)。perf_counter は perfq から求めた実行率で
                    157:        // 小数以下を四捨五入する (のでこっちは 100% なら 100)。
1.1.1.3   root      158:        uint perf_counter {};                   // 実行率 [%]
1.1       root      159:        FixedQueue<uint32, 3> perfq {}; // 移動平均用のバッファ
                    160:        uint64 next_perf_rtime {};              // 次回測定予定の実経過時間
                    161:        uint64 last_perf_rtime {};              // 前回測定時の実経過時間
                    162:        uint64 last_perf_vtime {};              // 前回測定時の仮想経過時間
1.1.1.7   root      163:        uint clock_khz {};                              // MHz 表示用の定格クロック数
1.1       root      164: 
1.1.1.3   root      165:        MPU680x0Device *mpu680x0 {};
1.1.1.8   root      166:        ThreadManager *thman {};
1.1.1.3   root      167: 
1.1       root      168:        // 同期イベント
1.1.1.7   root      169:        Event *sync_event {};
1.1       root      170: };
                    171: 
1.1.1.9 ! root      172: inline Syncer *GetSyncer() {
1.1       root      173:        return Object::GetObject<Syncer>(OBJ_SYNCER);
                    174: }

unix.superglobalmegacorp.com

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