mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-25 16:31:42 +00:00
Ensures video interrupts can't be missed by a suitably-timed access.
This commit is contained in:
parent
72884f37c3
commit
8093f67173
@ -96,7 +96,7 @@ template <class T, int multiplier = 1, int divider = 1, class LocalTimeScale = H
|
|||||||
/// This does not affect this actor's record of when the next sequence point will occur.
|
/// This does not affect this actor's record of when the next sequence point will occur.
|
||||||
forceinline void flush() {
|
forceinline void flush() {
|
||||||
if(!is_flushed_) {
|
if(!is_flushed_) {
|
||||||
is_flushed_ = true;
|
did_flush_ = is_flushed_ = true;
|
||||||
if constexpr (divider == 1) {
|
if constexpr (divider == 1) {
|
||||||
const auto duration = time_since_update_.template flush<TargetTimeScale>();
|
const auto duration = time_since_update_.template flush<TargetTimeScale>();
|
||||||
object_.run_for(duration);
|
object_.run_for(duration);
|
||||||
@ -108,12 +108,11 @@ template <class T, int multiplier = 1, int divider = 1, class LocalTimeScale = H
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates whether a sequence-point-caused flush will occur if the specified period is added.
|
/// Indicates whether a flush has occurred since the last call to did_flush().
|
||||||
forceinline bool will_flush(LocalTimeScale rhs) const {
|
forceinline bool did_flush() {
|
||||||
if constexpr (!has_sequence_points<T>::value) {
|
const bool did_flush = did_flush_;
|
||||||
return false;
|
did_flush_ = false;
|
||||||
}
|
return did_flush;
|
||||||
return rhs >= time_until_event_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns the number of cycles until the next sequence-point-based flush, if the embedded object
|
/// @returns the number of cycles until the next sequence-point-based flush, if the embedded object
|
||||||
@ -122,6 +121,14 @@ template <class T, int multiplier = 1, int divider = 1, class LocalTimeScale = H
|
|||||||
return time_until_event_;
|
return time_until_event_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Indicates whether a sequence-point-caused flush will occur if the specified period is added.
|
||||||
|
forceinline bool will_flush(LocalTimeScale rhs) const {
|
||||||
|
if constexpr (!has_sequence_points<T>::value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return rhs >= time_until_event_;
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates this template's record of the next sequence point.
|
/// Updates this template's record of the next sequence point.
|
||||||
void update_sequence_point() {
|
void update_sequence_point() {
|
||||||
if constexpr (has_sequence_points<T>::value) {
|
if constexpr (has_sequence_points<T>::value) {
|
||||||
@ -134,6 +141,7 @@ template <class T, int multiplier = 1, int divider = 1, class LocalTimeScale = H
|
|||||||
T object_;
|
T object_;
|
||||||
LocalTimeScale time_since_update_, time_until_event_;
|
LocalTimeScale time_since_update_, time_until_event_;
|
||||||
bool is_flushed_ = true;
|
bool is_flushed_ = true;
|
||||||
|
bool did_flush_ = false;
|
||||||
|
|
||||||
template <typename S, typename = void> struct has_sequence_points : std::false_type {};
|
template <typename S, typename = void> struct has_sequence_points : std::false_type {};
|
||||||
template <typename S> struct has_sequence_points<S, decltype(void(std::declval<S &>().get_next_sequence_point()))> : std::true_type {};
|
template <typename S> struct has_sequence_points<S, decltype(void(std::declval<S &>().get_next_sequence_point()))> : std::true_type {};
|
||||||
|
@ -719,13 +719,12 @@ class ConcreteMachine:
|
|||||||
update_interrupts();
|
update_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool will_flush_video = video_.will_flush(duration);
|
|
||||||
video_ += duration;
|
video_ += duration;
|
||||||
iwm_ += duration;
|
iwm_ += duration;
|
||||||
cycles_since_audio_update_ += duration;
|
cycles_since_audio_update_ += duration;
|
||||||
total += decltype(total)(duration.as_integral());
|
total += decltype(total)(duration.as_integral());
|
||||||
|
|
||||||
if(will_flush_video) {
|
if(video_.did_flush()) {
|
||||||
update_interrupts();
|
update_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user