Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 86ca6ebefec8
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6ef7224569ba
Choose a head ref
  • 6 commits
  • 5 files changed
  • 1 contributor

Commits on Dec 3, 2020

  1. Copy the full SHA
    ad3c327 View commit details

Commits on Dec 5, 2020

  1. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    47a4102 View commit details
  2. no loop

    eggrobin committed Dec 5, 2020
    Copy the full SHA
    3d4660f View commit details
  3. forwarding

    eggrobin committed Dec 5, 2020
    Copy the full SHA
    c30ca28 View commit details
  4. swap

    eggrobin committed Dec 5, 2020
    Copy the full SHA
    4df394b View commit details

Commits on Dec 11, 2020

  1. Merge pull request #2806 from eggrobin/no-waiting

    Stop unused analysers, reduce the analysis frequency in the background
    eggrobin authored Dec 11, 2020
    Copy the full SHA
    6ef7224 View commit details
Showing with 42 additions and 39 deletions.
  1. +2 −2 base/jthread_body.hpp
  2. +26 −27 ksp_plugin/orbit_analyser.cpp
  3. +3 −6 ksp_plugin/orbit_analyser.hpp
  4. +1 −1 ksp_plugin/vessel.cpp
  5. +10 −3 ksp_plugin_adapter/orbit_analyser.cs
4 changes: 2 additions & 2 deletions base/jthread_body.hpp
Original file line number Diff line number Diff line change
@@ -168,9 +168,9 @@ jthread MakeStoppableThread(Function&& f, Args&&... args) {
[f](stop_token const& st, Args&&... args) {
// This assignment happens on the thread of the jthread.
this_stoppable_thread::stop_token_ = st;
f(args...);
f(std::forward<Args>(args)...);
},
args...);
std::forward<Args>(args)...);
}

inline stop_token this_stoppable_thread::get_stop_token() {
53 changes: 26 additions & 27 deletions ksp_plugin/orbit_analyser.cpp
Original file line number Diff line number Diff line change
@@ -31,22 +31,26 @@ OrbitAnalyser::OrbitAnalyser(
analysed_trajectory_parameters_(
std::move(analysed_trajectory_parameters)) {}

void OrbitAnalyser::Restart() {
analyser_ = MakeStoppableThread([this] { RepeatedlyAnalyseOrbit(); });
void OrbitAnalyser::Interrupt() {
analyser_ = jthread();
}

void OrbitAnalyser::RequestAnalysis(Parameters const& parameters) {
if (!analyser_.joinable()) {
analyser_ = MakeStoppableThread([this] { RepeatedlyAnalyseOrbit(); });
}
Ephemeris<Barycentric>::Guard guard(ephemeris_);
if (ephemeris_->t_min() > parameters.first_time) {
// Too much has been forgotten; we cannot perform this analysis.
return;
}
last_parameters_ = parameters;
absl::MutexLock l(&lock_);
guarded_parameters_ = {std::move(guard), parameters};
// Only process this request if there is no analysis in progress.
if (!analyser_.joinable()) {
analyser_ = MakeStoppableThread(
[this](GuardedParameters guarded_parameters) {
AnalyseOrbit(std::move(guarded_parameters));
},
GuardedParameters{std::move(guard), parameters});
}
}

std::optional<OrbitAnalyser::Parameters> const& OrbitAnalyser::last_parameters()
@@ -70,25 +74,18 @@ double OrbitAnalyser::progress_of_next_analysis() const {
return progress_of_next_analysis_;
}

Status OrbitAnalyser::RepeatedlyAnalyseOrbit() {
for (;;) {
// No point in going faster than 50 Hz.
std::chrono::steady_clock::time_point const wakeup_time =
std::chrono::steady_clock::now() + std::chrono::milliseconds(20);

RETURN_IF_STOPPED;

std::optional<GuardedParameters> guarded_parameters;
{
absl::MutexLock l(&lock_);
if (!guarded_parameters_.has_value()) {
// No parameters, let's wait for them to appear.
continue;
}
std::swap(guarded_parameters, guarded_parameters_);
}

auto const& parameters = guarded_parameters->parameters;
Status OrbitAnalyser::AnalyseOrbit(GuardedParameters guarded_parameters) {
// This object will represent this thread once we are ready to detach from the
// main thread.
jthread analyser;
// The thread is joinable within the following block; it is detached outside
// of it, so anything whose destructor relies on objects that can be destroyed
// by the main thread should live within the block.
{
// Ensure that we destroy the guard before leaving the block, while we know
// that the ephemeris still exists.
GuardedParameters guarded = std::move(guarded_parameters);
auto const& parameters = guarded.parameters;

Analysis analysis{parameters.first_time};
DiscreteTrajectory<Barycentric> trajectory;
@@ -182,10 +179,12 @@ Status OrbitAnalyser::RepeatedlyAnalyseOrbit() {
{
absl::MutexLock l(&lock_);
next_analysis_ = std::move(analysis);
// Take ownership of our own thread so we can safely detach.
std::swap(analyser, analyser_);
}

std::this_thread::sleep_until(wakeup_time);
}
analyser.detach();
return Status::OK;
}

Instant const& OrbitAnalyser::Analysis::first_time() const {
9 changes: 3 additions & 6 deletions ksp_plugin/orbit_analyser.hpp
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ class OrbitAnalyser {

// Cancel any computation in progress, causing the next call to
// |RequestAnalysis| to be processed as fast as possible.
void Restart();
void Interrupt();

// Sets the parameters that will be used for the computation of the next
// analysis.
@@ -126,7 +126,7 @@ class OrbitAnalyser {
Parameters parameters;
};

Status RepeatedlyAnalyseOrbit();
Status AnalyseOrbit(GuardedParameters guarded_parameters);

not_null<Ephemeris<Barycentric>*> const ephemeris_;
Ephemeris<Barycentric>::FixedStepParameters const
@@ -137,10 +137,7 @@ class OrbitAnalyser {
std::optional<Analysis> analysis_;

mutable absl::Mutex lock_;
jthread analyser_;
// |parameters_| is set by the main thread; it is read and cleared by the
// |analyser_| thread.
std::optional<GuardedParameters> guarded_parameters_ GUARDED_BY(lock_);
jthread analyser_ GUARDED_BY(lock_);
// |next_analysis_| is set by the |analyser_| thread; it is read and cleared
// by the main thread.
std::optional<Analysis> next_analysis_ GUARDED_BY(lock_);
2 changes: 1 addition & 1 deletion ksp_plugin/vessel.cpp
Original file line number Diff line number Diff line change
@@ -524,7 +524,7 @@ void Vessel::RefreshOrbitAnalysis(Time const& mission_duration) {
if (orbit_analyser_->last_parameters().has_value() &&
orbit_analyser_->last_parameters()->mission_duration !=
mission_duration) {
orbit_analyser_->Restart();
orbit_analyser_->Interrupt();
}
orbit_analyser_->RequestAnalysis(
{.first_time = psychohistory_->back().time,
13 changes: 10 additions & 3 deletions ksp_plugin_adapter/orbit_analyser.cs
Original file line number Diff line number Diff line change
@@ -145,11 +145,17 @@ public OrbitAnalyser(PrincipiaPluginAdapter adapter,

public void RenderButton() {
string vessel_guid = predicted_vessel?.id.ToString();
var now = DateTime.UtcNow;
if (vessel_guid == null) {
orbit_description_ = null;
} else if (!Shown()) {
// Keep refreshing the analysis even when the analyser is not shown, so
// that the analysis button can display an up-to-date one-line summary.
} else if (
!Shown() &&
(!last_background_analysis_time_.HasValue ||
(now - last_background_analysis_time_) > TimeSpan.FromSeconds(2))) {
last_background_analysis_time_ = now;
// Keep refreshing the analysis (albeit at a reduced rate) even when the
// analyser is not shown, so that the analysis button can display an
// up-to-date one-line summary.
OrbitAnalysis analysis = plugin.VesselRefreshAnalysis(
vessel_guid,
mission_duration_.value,
@@ -505,6 +511,7 @@ private void LabeledField(string label, string value) {
private int ground_track_revolution_ = 1;

private string orbit_description_ = null;
private DateTime? last_background_analysis_time_ = null;
}