Skip to content

Commit

Permalink
Link graph: Fix MP desync when day length changed between job start a…
Browse files Browse the repository at this point in the history
…nd join

Add day length factor field to link graph job
  • Loading branch information
JGRennison committed Oct 10, 2024
1 parent 97f3075 commit 4e92b00
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/linkgraph/flowmapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void FlowMapper::Run(LinkGraphJob &job) const
* LinkGraph::Monthly(). */
uint runtime = (uint)Clamp<ScaledTickCounter>(job.StartTick() - job.LastCompression() + 1, 1, UINT32_MAX);
for (auto &it : flows) {
it.ScaleToMonthly(runtime);
it.ScaleToMonthly(runtime, job.DayLengthFactor());
}
}
/* Clear paths. */
Expand Down
6 changes: 6 additions & 0 deletions src/linkgraph/linkgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,9 @@ void LinkGraphFixupAfterLoad(bool compression_was_date)
convert(lgj->start_tick);
}
}

void LinkGraphJobSetDayLengthFactor() {
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
lgj->day_length_factor = DayLengthFactor();
}
}
1 change: 1 addition & 0 deletions src/linkgraph/linkgraphjob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ LinkGraphJob::LinkGraphJob(const LinkGraph &orig, uint duration_multiplier) :
settings(_settings_game.linkgraph),
join_tick(GetLinkGraphJobJoinTick(duration_multiplier)),
start_tick(_scaled_tick_counter),
day_length_factor(DayLengthFactor()),
job_completed(false),
job_aborted(false)
{
Expand Down
10 changes: 9 additions & 1 deletion src/linkgraph/linkgraphjob.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphJobDesc();
friend void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj);
friend void LinkGraphFixupAfterLoad(bool compression_was_date);
friend void LinkGraphJobSetDayLengthFactor();
friend class LinkGraphSchedule;
friend class LinkGraphJobGroup;

Expand All @@ -144,6 +145,7 @@ class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{
ScaledTickCounter start_tick; ///< Tick when the job was started.
NodeAnnotationVector nodes; ///< Extra node data necessary for link graph calculation.
EdgeAnnotationVector edges; ///< Edge data necessary for link graph calculation.
uint8_t day_length_factor; ///< Day length factor for this job
std::atomic<bool> job_completed; ///< Is the job still running. This is accessed by multiple threads and reads may be stale.
std::atomic<bool> job_aborted; ///< Has the job been aborted. This is accessed by multiple threads and reads may be stale.

Expand Down Expand Up @@ -264,7 +266,7 @@ class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{
* settings have to be brutally const-casted in order to populate them.
*/
LinkGraphJob() : settings(_settings_game.linkgraph),
join_tick(0), start_tick(0), job_completed(false), job_aborted(false) {}
join_tick(0), start_tick(0), day_length_factor(1), job_completed(false), job_aborted(false) {}

LinkGraphJob(const LinkGraph &orig, uint duration_multiplier);
~LinkGraphJob();
Expand Down Expand Up @@ -313,6 +315,12 @@ class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{
*/
inline ScaledTickCounter StartTick() const { return this->start_tick; }

/**
* Get the day length factor to use for this job.
* @return Day length factor.
*/
inline uint8_t DayLengthFactor() const { return this->day_length_factor; }

/**
* Set the tick when the job should be joined.
* @return Start date.
Expand Down
6 changes: 6 additions & 0 deletions src/saveload/afterload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,12 @@ bool AfterLoadGame()
LinkGraphFixupAfterLoad(SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE, 4));
}

/* Set link graph job day length factor setting. */
if (SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE, 7)) {
extern void LinkGraphJobSetDayLengthFactor();
LinkGraphJobSetDayLengthFactor();
}

/* Load the sprites */
GfxLoadSprites();
LoadStringWidthTable();
Expand Down
2 changes: 1 addition & 1 deletion src/sl/extended_ver_sl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", nullptr, nullptr, nullptr },
{ XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", nullptr, nullptr, nullptr },
{ XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", nullptr, nullptr, nullptr },
{ XSLFI_LINKGRAPH_DAY_SCALE, XSCF_NULL, 6, 6, "linkgraph_day_scale", nullptr, nullptr, nullptr },
{ XSLFI_LINKGRAPH_DAY_SCALE, XSCF_NULL, 7, 7, "linkgraph_day_scale", nullptr, nullptr, nullptr },
{ XSLFI_TEMPLATE_REPLACEMENT, XSCF_NULL, 10, 10, "template_replacement", nullptr, nullptr, "TRPL,TMPL" },
{ XSLFI_MORE_RAIL_TYPES, XSCF_NULL, 0, 1, "more_rail_types", nullptr, nullptr, nullptr },
{ XSLFI_CARGO_TYPE_ORDERS, XSCF_NULL, 4, 4, "cargo_type_orders", nullptr, nullptr, nullptr },
Expand Down
1 change: 1 addition & 0 deletions src/sl/linkgraph_sl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ NamedSaveLoadTable GetLinkGraphJobDesc()
NSL("start_tick", SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_FILE_I32 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 1, 4))),
NSL("start_tick", SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_FILE_I64 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 5, 5))),
NSL("start_tick", SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6))),
NSL("day_length_factor",SLE_CONDVAR_X(LinkGraphJob, day_length_factor,SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 7))),
NSL("link_graph.index", SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16)),
NSLT_STRUCT<LinkGraphJobStructHandler>("linkgraph"),
};
Expand Down
2 changes: 1 addition & 1 deletion src/station_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ class FlowStat {

void ReleaseShare(StationID st);

void ScaleToMonthly(uint runtime);
void ScaleToMonthly(uint runtime, uint8_t day_length_factor);

/**
* Return total amount of unrestricted shares.
Expand Down
5 changes: 3 additions & 2 deletions src/station_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5565,14 +5565,15 @@ void FlowStat::ReleaseShare(StationID st)
/**
* Scale all shares from link graph's runtime to monthly values.
* @param runtime Time the link graph has been running without compression, in scaled ticks.
* @param day_length_factor Day length factor to use.
* @pre runtime must be greater than 0 as we don't want infinite flow values.
*/
void FlowStat::ScaleToMonthly(uint runtime)
void FlowStat::ScaleToMonthly(uint runtime, uint8_t day_length_factor)
{
assert(runtime > 0);
uint share = 0;
for (iterator i = this->begin(); i != this->end(); ++i) {
share = std::max(share + 1, ClampTo<uint>((static_cast<uint64_t>(i->first) * 30 * DAY_TICKS * DayLengthFactor()) / runtime));
share = std::max(share + 1, ClampTo<uint>((static_cast<uint64_t>(i->first) * 30 * DAY_TICKS * day_length_factor) / runtime));
if (this->unrestricted == i->first) this->unrestricted = share;
i->first = share;
}
Expand Down

0 comments on commit 4e92b00

Please sign in to comment.