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

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: 
                     23:        // リクエストフラグ
                     24:        static const uint REQ_SYNC              = 0x0001;       // スケジューラを同期モードに
                     25:        static const uint REQ_FAST              = 0x0002;       // スケジューラを高速モードに
                     26:        static const uint REQ_RUN               = 0x0004;       // MPU が通常状態になった
                     27:        static const uint REQ_STOP              = 0x0008;       // MPU が STOP 状態になった
                     28:        static const uint REQ_MODEMASK  = 0x000f;       // mode マスク
                     29:        static const uint REQ_POWER_ON  = 0x0010;       // 電源オン
                     30:        static const uint REQ_POWER_OFF = 0x0020;       // 電源オフ
                     31:        static const uint REQ_EXIT              = 0x0040;       // アプリケーション終了
1.1.1.5   root       32:        static const uint REQ_RESET             = 0x0080;       // ハードウェアリセット
1.1       root       33: 
                     34:        // 動作モード
                     35:        // 動作モード変数 (mode) は高速モードか通常モードかと、MPU が通常状態が
                     36:        // STOP 状態かを同時に保持している。高速走行中であっても MPU が STOP 状態
                     37:        // なら通常走行するというロジックを比較1回で済ませるため。
                     38:        static const uint32 SCHED_STOP  = 0x0001;       // スケジューラが STOP 状態
                     39:        static const uint32 SCHED_SYNC  = 0x0002;       // 同期(%1)/高速(%0)モード
1.1.1.3   root       40: 
                     41:        // 演算を1回で済ませるために、この2値は同じ値にすること。
                     42:        // ただしこれをチェックするために全員が m68030.h/m88100.h を include すると
                     43:        // m88k を修正するたびに m68k も含めて全部ビルドが走るのはかなりつらいので
                     44:        // 定義されてる時だけチェックすることにする。
                     45:        // もともと将来のポカよけなのでビルド中1回でも通過すれば十分。
                     46: #if defined(CPU_REQ_STOP)
1.1       root       47:        static_assert(SCHED_STOP == CPU_REQ_STOP, "must be the same");
1.1.1.3   root       48: #endif
1.1       root       49: 
                     50:  public:
                     51:        Scheduler();
1.1.1.6 ! root       52:        virtual ~Scheduler() override;
1.1       root       53: 
1.1.1.3   root       54:        bool Init() override;
1.1       root       55: 
1.1.1.4   root       56:        nnSize GetMonitorSize() override;
                     57:        void MonitorUpdate(TextScreen&) override;
1.1       root       58: 
                     59:        // スレッド開始
                     60:        void ThreadRun();
                     61: 
1.1.1.2   root       62:        // スレッド終了
1.1       root       63:        void Terminate();
                     64: 
                     65:        // スケジューラを開始 (電源オン時に vm から呼ばれる)
                     66:        void Run();
                     67: 
                     68:        // 電源オフ要求
                     69:        void RequestPowerOff() {
                     70:                atomic_reqflag |= REQ_POWER_OFF;
                     71:        }
                     72: 
1.1.1.5   root       73:        // リセット要求
                     74:        void RequestResetHard() {
                     75:                atomic_reqflag |= REQ_RESET;
                     76:        }
                     77: 
1.1       root       78: 
                     79:        // スケジューラが高速モードなら true を返す。
                     80:        // ここでいう高速モードは STOP 状態中でも高速モード。
                     81:        bool GetFullSpeed() const { return ((mode & SCHED_SYNC) == 0); }
                     82: 
                     83:        // スケジューラの動作モードを設定する。
                     84:        // true なら高速モード、false なら同期モード。
                     85:        void SetFullSpeed(bool enable);
                     86: 
1.1.1.2   root       87:        // イベントを開始する
                     88:        void StartEvent(Event *newev);
                     89:        // イベントを停止する
                     90:        void StopEvent(Event *event);
1.1       root       91: 
                     92:        std::list<Event *> eventlist {};        // 有効なイベントリスト
                     93:        std::mutex evcs {};                                     // イベントリストのロック
                     94: 
                     95:        // 状態変更要求
                     96:        // スケジューラループの状態を変更したい場合はこのフラグを立てる。
                     97:        // REQ_MODE_* の相反するビット以外は同時に複数立ててもいいはず。
                     98:        // 処理されると再び 0 になる。
                     99:        std::atomic<uint32> atomic_reqflag {};
                    100:        std::condition_variable cv {};
                    101:        std::mutex cvmtx {};
                    102: 
                    103:  private:
1.1.1.5   root      104:        // リセットイベントコールバック
                    105:        void ResetCallback(Event& ev);
                    106: 
1.1.1.2   root      107:        pthread_t thread {};
1.1.1.5   root      108:        bool thread_created {};         // スレッドが作成されたら true
1.1.1.2   root      109: 
1.1       root      110:        // スケジューラの動作モード。SCHED_*
1.1.1.5   root      111:        uint32 mode {};
1.1       root      112: 
1.1.1.5   root      113:        uint64 rtimestart {};           // スケジューラ開始実時刻
                    114:        uint64 rtimebase {};            // 実時間の基準時刻
                    115:        uint64 vtimebase {};            // 仮想時間の基準時刻
1.1       root      116: 
                    117:        // 前回 RTC へ 32Hz 入力パルスを入れた時刻 (実時間の絶対時刻系)
1.1.1.5   root      118:        uint64 rtc_last_clock {};
1.1       root      119: };
                    120: 
1.1.1.2   root      121: extern std::unique_ptr<Scheduler> gScheduler;
1.1       root      122: 
                    123: // 現在時刻 [nsec] を取得する
                    124: static inline uint64 GetRealTime()
                    125: {
                    126:        struct timeval tv;
                    127:        gettimeofday(&tv, NULL);
                    128:        return (uint64)(tv.tv_sec * 1000 * 1000 + tv.tv_usec) * 1000;
                    129: }

unix.superglobalmegacorp.com

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