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

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: 
1.1.1.2 ! root       51:        // スレッド終了
1.1       root       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: 
1.1.1.2 ! root       85:        // イベントを開始する
        !            86:        void StartEvent(Event *newev);
        !            87:        // イベントを停止する
        !            88:        void StopEvent(Event *event);
1.1       root       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:
1.1.1.2 ! root      102:        pthread_t thread {};
        !           103:        bool thread_created = false;    // スレッドが作成されたら true
        !           104: 
1.1       root      105:        // スケジューラの動作モード。SCHED_*
                    106:        uint32 mode = 0;
                    107: 
                    108:        int mpu_clock = 0;                      // MPU クロック [kHz]
                    109: 
                    110:        uint64 rtimestart = 0;          // スケジューラ開始実時刻
                    111:        uint64 rtimebase = 0;           // 実時間の基準時刻
                    112:        uint64 vtimebase = 0;           // 仮想時間の基準時刻
                    113: 
                    114:        // 前回 RTC へ 32Hz 入力パルスを入れた時刻 (実時間の絶対時刻系)
                    115:        uint64 rtc_last_clock = 0;
                    116: };
                    117: 
1.1.1.2 ! root      118: extern std::unique_ptr<Scheduler> gScheduler;
1.1       root      119: 
                    120: // 現在時刻 [nsec] を取得する
                    121: static inline uint64 GetRealTime()
                    122: {
                    123:        struct timeval tv;
                    124:        gettimeofday(&tv, NULL);
                    125:        return (uint64)(tv.tv_sec * 1000 * 1000 + tv.tv_usec) * 1000;
                    126: }

unix.superglobalmegacorp.com

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