|
|
nono 1.7.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
//
// スケジューラ
//
#pragma once
#include "thread.h"
#include "message.h"
#include "spscqueue.h"
#include <array>
#include <condition_variable>
#include <mutex>
class EventManager;
class Syncer;
// スケジューラ
class Scheduler : public ThreadDevice
{
using inherited = ThreadDevice;
private:
// リクエストフラグ
static const uint32 REQUEST_EXIT = 0x00000001; // 終了要求
static const uint32 REQUEST_MESSAGE = 1U << MessageID::MAX_REQUEST;
// メッセージハンドラを覚えておくための構造体
struct MessageHandler
{
Device *dev {};
MessageCallback_t func {};
};
public:
Scheduler();
~Scheduler() override;
bool Init() override;
bool Init2();
void StartTime();
// スレッド終了指示
void Terminate() override;
// 現在のマスター仮想時間を返す
uint64 GetVirtTime() const { return vtime; }
// イベントを開始する
void StartEvent(Event *ev);
void RestartEvent(Event *ev);
// 実時間間隔を指定してイベントを開始する。
// rt_now はイベント発行者の実時間での現在時刻で、
// rt_period は次回のイベントまでの実時間間隔。
void StartRealtimeEvent(Event *ev, uint64 rt_now, uint64 rt_period);
// イベントを停止する
void StopEvent(Event *ev);
// メッセージハンドラを登録する
void ConnectMessage(MessageID, Device *, MessageCallback_t);
// メッセージを送る。VM スレッド以外からも呼び出して良い。
void SendMessage(MessageID, uint32 arg = 0);
// 指定時間が経過するか、リクエストが起きるまでスリープ
void Sleep(uint64 time);
private:
// スレッド
void ThreadRun() override;
void EnqueueSlow(Event *);
void PushSlow(Event *);
void StopSlowEvent(Event *);
// メッセージディスパッチ
void DispatchMessage();
void InvokeMessage(MessageID, uint32);
DECLARE_MONITOR_SCREEN(MonitorScreen);
// 有効なイベントキュー
uint64 slow_top_vtime {};
Event *fast {};
int slow_top {};
std::array<Event *, 64> slow {};
// 現在の仮想経過時間
uint64 vtime {};
// 外部スレッドからのリクエスト
uint32 request {};
std::mutex mtx {};
std::condition_variable cv {};
// メッセージハンドラリスト
std::array<MessageHandler, MessageID::MAX> message_handlers {};
// メッセージキュー
SPSCQueue<uint64, 64> msgq {};
EventManager *evman {};
Syncer *syncer {};
Monitor *monitor {};
};
inline Scheduler *GetScheduler() {
return Object::GetObject<Scheduler>(OBJ_SCHEDULER);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.