Annotation of nono/vm/scheduler.h, revision 1.1.1.7

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #pragma once
                      8: 
1.1.1.3   root        9: #include "device.h"
                     10: #include "event.h"
                     11: #include "mpu.h"
1.1       root       12: #include <atomic>
                     13: #include <condition_variable>
1.1.1.3   root       14: #include <list>
1.1       root       15: #include <mutex>
                     16: #include <pthread.h>
                     17: 
                     18: // スケジューラ
                     19: class Scheduler : public Device
                     20: {
1.1.1.3   root       21:        using inherited = Device;
1.1       root       22: 
1.1.1.7 ! root       23:  public:
        !            24:        // 動作モード
        !            25:        // 動作モード変数 (mode) はスケジューラの走行状態を表している。以下の
        !            26:        // ビットがすべて %0 なら高速モード、どれかでも %1 なら通常モードになる。
        !            27:        //
        !            28:        //      | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
        !            29:        // mode |                        |SYNC| CPUSTAT |
        !            30:        //                                 |     +---+---- CPU の状態
        !            31:        //                                 +-------------- 高速モード抑制
        !            32:        //
        !            33:        // bit1,0 (CPUSTAT) は CPU の状態を示す。%00 の時だけ高速走行が可能。
        !            34:        // これは MPUDevice::Run() の戻り値でもある。
        !            35:        //   b1 b0
        !            36:        //    0  0  通常状態
        !            37:        //    0  1  STOP 状態 (m88k なら擬似 STOP 状態)
        !            38:        //    1  0  HALT 状態 (ダブルバスフォールト)
        !            39:        //    1  1  HALT 状態だがこちらのビットパターンは使わない
        !            40:        //
        !            41:        // bit2 (SYNC) が UI からの高速モード指示。%0 なら高速、%1 なら通常。
        !            42:        // なのでどっちかというと高速モード抑制指示というほうがいいかも。
        !            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: 
        !            48:        // 便宜上用意しておく
        !            49:        static const uint32 SCHED_CPU_NORMAL= 0x0000;   // CPU が通常状態
        !            50:        static const uint32 SCHED_CPU_MASK = (SCHED_CPU_STOP | SCHED_CPU_HALT);
        !            51: 
        !            52:  private:
1.1       root       53:        // リクエストフラグ
1.1.1.7 ! root       54:        // REQ_CPU_MODE は CPU mode が何らか変化することのフラグ。どの状態に変化
        !            55:        // するかは new_cpumode 変数で示す。1回のループ期間中に複数回の変化が
        !            56:        // 起きても最終状態だけに変化するため。
        !            57:        // REQ_USER_MODE と new_usermode も同様。
        !            58:        static const uint REQ_CPU_MODE  = 0x0001;       // CPU 状態を変更
        !            59:        static const uint REQ_USER_MODE = 0x0002;       // 同期/高速モード変更
1.1       root       60:        static const uint REQ_POWER_ON  = 0x0010;       // 電源オン
                     61:        static const uint REQ_POWER_OFF = 0x0020;       // 電源オフ
                     62:        static const uint REQ_EXIT              = 0x0040;       // アプリケーション終了
1.1.1.5   root       63:        static const uint REQ_RESET             = 0x0080;       // ハードウェアリセット
1.1       root       64: 
                     65:  public:
                     66:        Scheduler();
1.1.1.6   root       67:        virtual ~Scheduler() override;
1.1       root       68: 
1.1.1.3   root       69:        bool Init() override;
1.1       root       70: 
1.1.1.4   root       71:        nnSize GetMonitorSize() override;
                     72:        void MonitorUpdate(TextScreen&) override;
1.1       root       73: 
                     74:        // スレッド開始
                     75:        void ThreadRun();
                     76: 
1.1.1.2   root       77:        // スレッド終了
1.1       root       78:        void Terminate();
                     79: 
                     80:        // スケジューラを開始 (電源オン時に vm から呼ばれる)
                     81:        void Run();
                     82: 
                     83:        // 電源オフ要求
                     84:        void RequestPowerOff() {
                     85:                atomic_reqflag |= REQ_POWER_OFF;
                     86:        }
                     87: 
1.1.1.5   root       88:        // リセット要求
                     89:        void RequestResetHard() {
                     90:                atomic_reqflag |= REQ_RESET;
                     91:        }
                     92: 
1.1       root       93: 
                     94:        // スケジューラが高速モードなら true を返す。
                     95:        // ここでいう高速モードは STOP 状態中でも高速モード。
                     96:        bool GetFullSpeed() const { return ((mode & SCHED_SYNC) == 0); }
                     97: 
                     98:        // スケジューラの動作モードを設定する。
                     99:        // true なら高速モード、false なら同期モード。
                    100:        void SetFullSpeed(bool enable);
                    101: 
1.1.1.2   root      102:        // イベントを開始する
                    103:        void StartEvent(Event *newev);
                    104:        // イベントを停止する
                    105:        void StopEvent(Event *event);
1.1       root      106: 
                    107:        std::list<Event *> eventlist {};        // 有効なイベントリスト
                    108:        std::mutex evcs {};                                     // イベントリストのロック
                    109: 
                    110:        // 状態変更要求
                    111:        // スケジューラループの状態を変更したい場合はこのフラグを立てる。
                    112:        // REQ_MODE_* の相反するビット以外は同時に複数立ててもいいはず。
                    113:        // 処理されると再び 0 になる。
                    114:        std::atomic<uint32> atomic_reqflag {};
                    115:        std::condition_variable cv {};
                    116:        std::mutex cvmtx {};
                    117: 
                    118:  private:
1.1.1.5   root      119:        // リセットイベントコールバック
                    120:        void ResetCallback(Event& ev);
                    121: 
1.1.1.7 ! root      122:        // スレッド終了を指示する
        !           123:        void RequestExit();
        !           124: 
1.1.1.2   root      125:        pthread_t thread {};
1.1.1.5   root      126:        bool thread_created {};         // スレッドが作成されたら true
1.1.1.2   root      127: 
1.1       root      128:        // スケジューラの動作モード。SCHED_*
1.1.1.5   root      129:        uint32 mode {};
1.1       root      130: 
1.1.1.7 ! root      131:        // REQ_CPU_MODE フラグで変更するモード
        !           132:        uint32 new_cpumode {};
        !           133: 
        !           134:        // REQ_USER_MODE フラグで変更するモード
        !           135:        uint32 new_usermode {};
        !           136: 
1.1.1.5   root      137:        uint64 rtimestart {};           // スケジューラ開始実時刻
                    138:        uint64 rtimebase {};            // 実時間の基準時刻
                    139:        uint64 vtimebase {};            // 仮想時間の基準時刻
1.1       root      140: 
                    141:        // 前回 RTC へ 32Hz 入力パルスを入れた時刻 (実時間の絶対時刻系)
1.1.1.5   root      142:        uint64 rtc_last_clock {};
1.1       root      143: };
                    144: 
1.1.1.2   root      145: extern std::unique_ptr<Scheduler> gScheduler;
1.1       root      146: 
                    147: // 現在時刻 [nsec] を取得する
                    148: static inline uint64 GetRealTime()
                    149: {
                    150:        struct timeval tv;
                    151:        gettimeofday(&tv, NULL);
                    152:        return (uint64)(tv.tv_sec * 1000 * 1000 + tv.tv_usec) * 1000;
                    153: }

unix.superglobalmegacorp.com

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