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

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2017 [email protected]
        !             4: //
        !             5: 
        !             6: #pragma once
        !             7: 
        !             8: #include <atomic>
        !             9: #include <condition_variable>
        !            10: #include <mutex>
        !            11: #include <pthread.h>
        !            12: #include "device.h"
        !            13: #include "event.h"
        !            14: #include "mpu.h"
        !            15: 
        !            16: // スケジューラ
        !            17: class Scheduler : public Device
        !            18: {
        !            19:        typedef Device inherited;
        !            20: 
        !            21:        // リクエストフラグ
        !            22:        static const uint REQ_SYNC              = 0x0001;       // スケジューラを同期モードに
        !            23:        static const uint REQ_FAST              = 0x0002;       // スケジューラを高速モードに
        !            24:        static const uint REQ_RUN               = 0x0004;       // MPU が通常状態になった
        !            25:        static const uint REQ_STOP              = 0x0008;       // MPU が STOP 状態になった
        !            26:        static const uint REQ_MODEMASK  = 0x000f;       // mode マスク
        !            27:        static const uint REQ_POWER_ON  = 0x0010;       // 電源オン
        !            28:        static const uint REQ_POWER_OFF = 0x0020;       // 電源オフ
        !            29:        static const uint REQ_EXIT              = 0x0040;       // アプリケーション終了
        !            30: 
        !            31:        // 動作モード
        !            32:        // 動作モード変数 (mode) は高速モードか通常モードかと、MPU が通常状態が
        !            33:        // STOP 状態かを同時に保持している。高速走行中であっても MPU が STOP 状態
        !            34:        // なら通常走行するというロジックを比較1回で済ませるため。
        !            35:        static const uint32 SCHED_STOP  = 0x0001;       // スケジューラが STOP 状態
        !            36:        static const uint32 SCHED_SYNC  = 0x0002;       // 同期(%1)/高速(%0)モード
        !            37:        // 演算を1回で済ませるために、同じ値にすること
        !            38:        static_assert(SCHED_STOP == CPU_REQ_STOP, "must be the same");
        !            39: 
        !            40:  public:
        !            41:        Scheduler();
        !            42:        virtual ~Scheduler();
        !            43: 
        !            44:        virtual bool Init();
        !            45: 
        !            46:        virtual bool MonitorUpdate();
        !            47: 
        !            48:        // スレッド開始
        !            49:        void ThreadRun();
        !            50: 
        !            51:        // スレッド終了指示
        !            52:        void Terminate();
        !            53: 
        !            54:        // スケジューラを開始 (電源オン時に vm から呼ばれる)
        !            55:        void Run();
        !            56: 
        !            57:        // 電源オフ要求
        !            58:        void RequestPowerOff() {
        !            59:                atomic_reqflag |= REQ_POWER_OFF;
        !            60:        }
        !            61: 
        !            62:        // サイクル数を仮想時間 [nsec] に変換
        !            63:        uint64 Cycle2Vtime(uint64 cycle) const {
        !            64:                return cycle * 1000 * 1000 / mpu_clock;
        !            65:        }
        !            66: 
        !            67:        // 仮想時間 [nsec] をサイクル数に変換
        !            68:        uint64 Vtime2Cycle(uint64 vtime) const {
        !            69:                return vtime * mpu_clock / (1000 * 1000);
        !            70:        }
        !            71: 
        !            72:        // 仮想時刻取得
        !            73:        uint64 GetVirtTime() const {
        !            74:                return Cycle2Vtime(gMPU->total_cycle());
        !            75:        }
        !            76: 
        !            77:        // スケジューラが高速モードなら true を返す。
        !            78:        // ここでいう高速モードは STOP 状態中でも高速モード。
        !            79:        bool GetFullSpeed() const { return ((mode & SCHED_SYNC) == 0); }
        !            80: 
        !            81:        // スケジューラの動作モードを設定する。
        !            82:        // true なら高速モード、false なら同期モード。
        !            83:        void SetFullSpeed(bool enable);
        !            84: 
        !            85:        // イベントを登録する
        !            86:        void AddEvent(Event *newev);
        !            87:        // イベントを削除する
        !            88:        void DelEvent(Event *event);
        !            89: 
        !            90:        std::list<Event *> eventlist {};        // 有効なイベントリスト
        !            91:        std::mutex evcs {};                                     // イベントリストのロック
        !            92: 
        !            93:        // 状態変更要求
        !            94:        // スケジューラループの状態を変更したい場合はこのフラグを立てる。
        !            95:        // REQ_MODE_* の相反するビット以外は同時に複数立ててもいいはず。
        !            96:        // 処理されると再び 0 になる。
        !            97:        std::atomic<uint32> atomic_reqflag {};
        !            98:        std::condition_variable cv {};
        !            99:        std::mutex cvmtx {};
        !           100: 
        !           101:  private:
        !           102:        // スケジューラの動作モード。SCHED_*
        !           103:        uint32 mode = 0;
        !           104: 
        !           105:        int mpu_clock = 0;                      // MPU クロック [kHz]
        !           106: 
        !           107:        uint64 rtimestart = 0;          // スケジューラ開始実時刻
        !           108:        uint64 rtimebase = 0;           // 実時間の基準時刻
        !           109:        uint64 vtimebase = 0;           // 仮想時間の基準時刻
        !           110: 
        !           111:        // 前回 RTC へ 32Hz 入力パルスを入れた時刻 (実時間の絶対時刻系)
        !           112:        uint64 rtc_last_clock = 0;
        !           113: };
        !           114: 
        !           115: extern Scheduler *gScheduler;
        !           116: 
        !           117: // 現在時刻 [nsec] を取得する
        !           118: static inline uint64 GetRealTime()
        !           119: {
        !           120:        struct timeval tv;
        !           121:        gettimeofday(&tv, NULL);
        !           122:        return (uint64)(tv.tv_sec * 1000 * 1000 + tv.tv_usec) * 1000;
        !           123: }

unix.superglobalmegacorp.com

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