File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / scheduler.h
Revision 1.1.1.17 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:06:01 2026 UTC (3 months ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
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);
}

unix.superglobalmegacorp.com

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