mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-08 14:25:05 +00:00
Start experimenting with a more event-based approach to timing.
This commit is contained in:
77
Concurrency/AsyncUpdater.hpp
Normal file
77
Concurrency/AsyncUpdater.hpp
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// AsyncUpdater.h
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 06/07/2022.
|
||||||
|
// Copyright © 2022 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AsyncUpdater_hpp
|
||||||
|
#define AsyncUpdater_hpp
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "../ClockReceiver/TimeTypes.hpp"
|
||||||
|
|
||||||
|
namespace Concurrency {
|
||||||
|
|
||||||
|
template <typename Performer> class AsyncUpdater {
|
||||||
|
public:
|
||||||
|
template <typename... Args> AsyncUpdater(Args&&... args)
|
||||||
|
: performer_(std::forward<Args>(args)...),
|
||||||
|
performer_thread_{
|
||||||
|
[this] {
|
||||||
|
Time::Nanos last_fired = Time::nanos_now();
|
||||||
|
|
||||||
|
while(!should_quit) {
|
||||||
|
// Wait for a new action to be signalled, and grab it.
|
||||||
|
std::unique_lock lock(condition_mutex_);
|
||||||
|
while(actions_.empty()) {
|
||||||
|
condition_.wait(lock);
|
||||||
|
}
|
||||||
|
auto action = actions_.pop_back();
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
// Update to now.
|
||||||
|
auto time_now = Time::nanos_now();
|
||||||
|
performer_.perform(time_now - last_fired);
|
||||||
|
last_fired = time_now;
|
||||||
|
|
||||||
|
// Perform the action.
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
/// Run the performer up to 'now' and then perform @c post_action.
|
||||||
|
///
|
||||||
|
/// @c post_action will be performed asynchronously, on the same
|
||||||
|
/// thread as the performer.
|
||||||
|
void update(const std::function<void(void)> &post_action) {
|
||||||
|
std::lock_guard guard(condition_mutex_);
|
||||||
|
actions_.push_back(post_action);
|
||||||
|
condition_.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
~AsyncUpdater() {
|
||||||
|
should_quit = true;
|
||||||
|
update([] {});
|
||||||
|
performer_thread_.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Performer performer_;
|
||||||
|
|
||||||
|
std::thread performer_thread_;
|
||||||
|
std::mutex condition_mutex_;
|
||||||
|
std::condition_variable condition_;
|
||||||
|
std::vector<std::function<void(void)>> actions_;
|
||||||
|
std::atomic<bool> should_quit = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* AsyncUpdater_hpp */
|
@@ -2138,6 +2138,7 @@
|
|||||||
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = "<group>"; };
|
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = "<group>"; };
|
||||||
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = "<group>"; };
|
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = "<group>"; };
|
||||||
4BE0151C286A8C8E00EA42E9 /* MemorySwitches.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MemorySwitches.hpp; sourceTree = "<group>"; };
|
4BE0151C286A8C8E00EA42E9 /* MemorySwitches.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MemorySwitches.hpp; sourceTree = "<group>"; };
|
||||||
|
4BE0151E28766ECF00EA42E9 /* AsyncUpdater.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AsyncUpdater.hpp; sourceTree = "<group>"; };
|
||||||
4BE0A3EC237BB170002AB46F /* ST.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ST.cpp; sourceTree = "<group>"; };
|
4BE0A3EC237BB170002AB46F /* ST.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ST.cpp; sourceTree = "<group>"; };
|
||||||
4BE0A3ED237BB170002AB46F /* ST.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ST.hpp; sourceTree = "<group>"; };
|
4BE0A3ED237BB170002AB46F /* ST.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ST.hpp; sourceTree = "<group>"; };
|
||||||
4BE211DD253E4E4800435408 /* 65C02_no_Rockwell_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = 65C02_no_Rockwell_test.bin; path = "Klaus Dormann/65C02_no_Rockwell_test.bin"; sourceTree = "<group>"; };
|
4BE211DD253E4E4800435408 /* 65C02_no_Rockwell_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = 65C02_no_Rockwell_test.bin; path = "Klaus Dormann/65C02_no_Rockwell_test.bin"; sourceTree = "<group>"; };
|
||||||
@@ -2754,6 +2755,7 @@
|
|||||||
children = (
|
children = (
|
||||||
4B3940E51DA83C8300427841 /* AsyncTaskQueue.cpp */,
|
4B3940E51DA83C8300427841 /* AsyncTaskQueue.cpp */,
|
||||||
4B3940E61DA83C8300427841 /* AsyncTaskQueue.hpp */,
|
4B3940E61DA83C8300427841 /* AsyncTaskQueue.hpp */,
|
||||||
|
4BE0151E28766ECF00EA42E9 /* AsyncUpdater.hpp */,
|
||||||
);
|
);
|
||||||
name = Concurrency;
|
name = Concurrency;
|
||||||
path = ../../Concurrency;
|
path = ../../Concurrency;
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "../../../../ClockReceiver/TimeTypes.hpp"
|
#include "../../../../ClockReceiver/TimeTypes.hpp"
|
||||||
#include "../../../../ClockReceiver/ScanSynchroniser.hpp"
|
#include "../../../../ClockReceiver/ScanSynchroniser.hpp"
|
||||||
|
#include "../../../../Concurrency/AsyncUpdater.hpp"
|
||||||
|
|
||||||
#import "CSStaticAnalyser+TargetVector.h"
|
#import "CSStaticAnalyser+TargetVector.h"
|
||||||
#import "NSBundle+DataResource.h"
|
#import "NSBundle+DataResource.h"
|
||||||
@@ -34,6 +35,14 @@
|
|||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct Updater {};
|
||||||
|
|
||||||
|
Concurrency::AsyncUpdater<Updater> updater();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@interface CSMachine() <CSScanTargetViewDisplayLinkDelegate>
|
@interface CSMachine() <CSScanTargetViewDisplayLinkDelegate>
|
||||||
- (void)speaker:(Outputs::Speaker::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
|
- (void)speaker:(Outputs::Speaker::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
|
||||||
- (void)speakerDidChangeInputClock:(Outputs::Speaker::Speaker *)speaker;
|
- (void)speakerDidChangeInputClock:(Outputs::Speaker::Speaker *)speaker;
|
||||||
|
Reference in New Issue
Block a user