diff --git a/ClockReceiver/Sleeper.h b/ClockReceiver/Sleeper.h new file mode 100644 index 000000000..caa837cf8 --- /dev/null +++ b/ClockReceiver/Sleeper.h @@ -0,0 +1,46 @@ +// +// Sleeper.h +// Clock Signal +// +// Created by Thomas Harte on 20/08/2017. +// Copyright © 2017 Thomas Harte. All rights reserved. +// + +#ifndef Sleeper_h +#define Sleeper_h + +/*! + A sleeper is any component that sometimes requires a clock but at other times is 'asleep' — i.e. is not doing + any clock-derived work, so needn't receive a clock. A disk controller is an archetypal example. + + A sleeper will signal sleeps and wakes to an observer. + + This is intended to allow for performance improvements to machines with components that can sleep. The observer + callout is virtual so the intended use case is that a machine holds a component that might sleep. Its transitions + into and out of sleep are sufficiently infrequent that a virtual call to announce them costs sufficiently little that + the saved ::run_fors add up to a substantial amount. + + By convention, sleeper components must be willing to accept ::run_for even after announcing sleep. It's a hint, + not a command. +*/ +class Sleeper { + public: + Sleeper() : sleep_observer_(nullptr) {} + + class SleepObserver { + public: + /// Called to inform an observer that the component @c component has either gone to sleep or become awake. + void set_component_is_sleeping(void *component, bool is_sleeping) = 0; + }; + + /// Registers @c observer as the new sleep observer; + void set_sleep_observer(SleepObserver *observer) { + sleep_observer_ = delegate; + } + + protected: + /// Provided for subclasses; send sleep announcements to the sleep_observer_. + SleepObserver *sleep_observer_; +}; + +#endif /* Sleeper_h */ diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 106529857..7ed659817 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -678,6 +678,7 @@ 4BAD9B941F43D7E900724854 /* UnformattedTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnformattedTrack.cpp; sourceTree = ""; }; 4BAD9B951F43D7E900724854 /* UnformattedTrack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = UnformattedTrack.hpp; sourceTree = ""; }; 4BB06B211F316A3F00600C7A /* ForceInline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ForceInline.h; sourceTree = ""; }; + 4BB146C61F49D7D700253439 /* Sleeper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Sleeper.h; sourceTree = ""; }; 4BB17D4C1ED7909F00ABD1E1 /* tests.expected.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = tests.expected.json; path = FUSE/tests.expected.json; sourceTree = ""; }; 4BB17D4D1ED7909F00ABD1E1 /* tests.in.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = tests.in.json; path = FUSE/tests.in.json; sourceTree = ""; }; 4BB297E51B587D8300A49093 /* start */ = {isa = PBXFileReference; lastKnownFileType = file; path = " start"; sourceTree = ""; }; @@ -2280,6 +2281,7 @@ children = ( 4BF6606A1F281573002CB053 /* ClockReceiver.hpp */, 4BB06B211F316A3F00600C7A /* ForceInline.h */, + 4BB146C61F49D7D700253439 /* Sleeper.h */, ); name = ClockReceiver; path = ../../ClockReceiver;