Index: src/station.cpp
===================================================================
--- src/station.cpp (revision 27177)
+++ src/station.cpp (working copy)
@@ -107,7 +107,7 @@
}
lg->RemoveNode(this->goods[c].node);
if (lg->Size() == 0) {
- LinkGraphSchedule::Instance()->Unqueue(lg);
+ LinkGraphSchedule::instance.Unqueue(lg);
delete lg;
}
}
Index: src/station_base.h
===================================================================
--- src/station_base.h (revision 27177)
+++ src/station_base.h (working copy)
@@ -37,6 +37,8 @@
public:
typedef std::map<uint32, StationID> SharesMap;
+ static const SharesMap empty_sharesmap;
+
/**
* Invalid constructor. This can't be called as a FlowStat must not be
* empty. However, the constructor must be defined and reachable for
Index: src/toolbar_gui.cpp
===================================================================
--- src/toolbar_gui.cpp (revision 27177)
+++ src/toolbar_gui.cpp (working copy)
@@ -1119,7 +1119,7 @@
_settings_game.game_creation.starting_year = Clamp(year, MIN_YEAR, MAX_YEAR);
Date new_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
/* If you open a savegame as scenario there may already be link graphs.*/
- LinkGraphSchedule::Instance()->ShiftDates(new_date - _date);
+ LinkGraphSchedule::instance.ShiftDates(new_date - _date);
SetDate(new_date, 0);
}
Index: src/saveload/linkgraph_sl.cpp
===================================================================
--- src/saveload/linkgraph_sl.cpp (revision 27177)
+++ src/saveload/linkgraph_sl.cpp (working copy)
@@ -209,7 +209,7 @@
*/
static void Load_LGRS()
{
- SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
+ SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
}
/**
@@ -218,7 +218,7 @@
*/
void AfterLoadLinkGraphs()
{
- LinkGraphSchedule::Instance()->SpawnAll();
+ LinkGraphSchedule::instance.SpawnAll();
}
/**
@@ -250,7 +250,7 @@
*/
static void Save_LGRS()
{
- SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
+ SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
}
/**
@@ -258,7 +258,7 @@
*/
static void Ptrs_LGRS()
{
- SlObject(LinkGraphSchedule::Instance(), GetLinkGraphScheduleDesc());
+ SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
}
extern const ChunkHandler _linkgraph_chunk_handlers[] = {
Index: src/cheat_gui.cpp
===================================================================
--- src/cheat_gui.cpp (revision 27177)
+++ src/cheat_gui.cpp (working copy)
@@ -102,7 +102,7 @@
if (p1 == _cur_year) return _cur_year;
Date new_date = ConvertYMDToDate(p1, ymd.month, ymd.day);
- LinkGraphSchedule::Instance()->ShiftDates(new_date - _date);
+ LinkGraphSchedule::instance.ShiftDates(new_date - _date);
SetDate(new_date, _date_fract);
EnginesMonthlyLoop();
SetWindowDirty(WC_STATUS_BAR, 0);
Index: src/linkgraph/linkgraphschedule.h
===================================================================
--- src/linkgraph/linkgraphschedule.h (revision 27177)
+++ src/linkgraph/linkgraphschedule.h (working copy)
@@ -51,8 +51,8 @@
public:
/* This is a tick where not much else is happening, so a small lag might go unnoticed. */
static const uint SPAWN_JOIN_TICK = 21; ///< Tick when jobs are spawned or joined every day.
+ static LinkGraphSchedule instance;
- static LinkGraphSchedule *Instance();
static void Run(void *j);
static void Clear();
Index: src/linkgraph/mcf.cpp
===================================================================
--- src/linkgraph/mcf.cpp (revision 27177)
+++ src/linkgraph/mcf.cpp (working copy)
@@ -146,15 +146,14 @@
*/
void SetNode(NodeID source, NodeID node)
{
- static const FlowStat::SharesMap empty;
const FlowStatMap &flows = this->job[node].Flows();
FlowStatMap::const_iterator it = flows.find(this->job[source].Station());
if (it != flows.end()) {
this->it = it->second.GetShares()->begin();
this->end = it->second.GetShares()->end();
} else {
- this->it = empty.begin();
- this->end = empty.end();
+ this->it = FlowStat::empty_sharesmap.begin();
+ this->end = FlowStat::empty_sharesmap.end();
}
}
@@ -378,11 +377,10 @@
*/
bool MCF1stPass::EliminateCycles(PathVector &path, NodeID origin_id, NodeID next_id)
{
- static Path *invalid_path = new Path(INVALID_NODE, true);
Path *at_next_pos = path[next_id];
/* this node has already been searched */
- if (at_next_pos == invalid_path) return false;
+ if (at_next_pos == Path::invalid_path) return false;
if (at_next_pos == NULL) {
/* Summarize paths; add up the paths with the same source and next hop
@@ -430,7 +428,7 @@
* could be found in this branch, thus it has to be searched again next
* time we spot it.
*/
- path[next_id] = found ? NULL : invalid_path;
+ path[next_id] = found ? NULL : Path::invalid_path;
return found;
}
Index: src/linkgraph/linkgraphjob.cpp
===================================================================
--- src/linkgraph/linkgraphjob.cpp (revision 27177)
+++ src/linkgraph/linkgraphjob.cpp (working copy)
@@ -20,6 +20,13 @@
INSTANTIATE_POOL_METHODS(LinkGraphJob)
/**
+ * Static instance of an invalid path.
+ * Note: This instance is created on task start.
+ * Lazy creation on first usage results in a data race between the CDist threads.
+ */
+/* static */ Path *Path::invalid_path = new Path(INVALID_NODE, true);
+
+/**
* Create a link graph job from a link graph. The link graph will be copied so
* that the calculations don't interfer with the normal operations on the
* original. The job is immediately started.
Index: src/linkgraph/linkgraphjob.h
===================================================================
--- src/linkgraph/linkgraphjob.h (revision 27177)
+++ src/linkgraph/linkgraphjob.h (working copy)
@@ -343,6 +343,8 @@
*/
class Path {
public:
+ static Path *invalid_path;
+
Path(NodeID n, bool source = false);
/** Get the node this leg passes. */
Index: src/linkgraph/linkgraphschedule.cpp
===================================================================
--- src/linkgraph/linkgraphschedule.cpp (revision 27177)
+++ src/linkgraph/linkgraphschedule.cpp (working copy)
@@ -17,6 +17,13 @@
#include "flowmapper.h"
/**
+ * Static instance of LinkGraphSchedule.
+ * Note: This instance is created on task start.
+ * Lazy creation on first usage results in a data race between the CDist threads.
+ */
+/* static */ LinkGraphSchedule LinkGraphSchedule::instance;
+
+/**
* Start the next job in the schedule.
*/
void LinkGraphSchedule::SpawnNext()
@@ -66,9 +73,8 @@
/* static */ void LinkGraphSchedule::Run(void *j)
{
LinkGraphJob *job = (LinkGraphJob *)j;
- LinkGraphSchedule *schedule = LinkGraphSchedule::Instance();
- for (uint i = 0; i < lengthof(schedule->handlers); ++i) {
- schedule->handlers[i]->Run(*job);
+ for (uint i = 0; i < lengthof(instance.handlers); ++i) {
+ instance.handlers[i]->Run(*job);
}
}
@@ -88,12 +94,11 @@
*/
/* static */ void LinkGraphSchedule::Clear()
{
- LinkGraphSchedule *inst = LinkGraphSchedule::Instance();
- for (JobList::iterator i(inst->running.begin()); i != inst->running.end(); ++i) {
+ for (JobList::iterator i(instance.running.begin()); i != instance.running.end(); ++i) {
(*i)->JoinThread();
}
- inst->running.clear();
- inst->schedule.clear();
+ instance.running.clear();
+ instance.schedule.clear();
}
/**
@@ -134,15 +139,6 @@
}
/**
- * Retrieve the link graph schedule or create it if necessary.
- */
-/* static */ LinkGraphSchedule *LinkGraphSchedule::Instance()
-{
- static LinkGraphSchedule inst;
- return &inst;
-}
-
-/**
* Spawn or join a link graph job or compress a link graph if any link graph is
* due to do so.
*/
@@ -151,9 +147,9 @@
if (_date_fract != LinkGraphSchedule::SPAWN_JOIN_TICK) return;
Date offset = _date % _settings_game.linkgraph.recalc_interval;
if (offset == 0) {
- LinkGraphSchedule::Instance()->SpawnNext();
+ LinkGraphSchedule::instance.SpawnNext();
} else if (offset == _settings_game.linkgraph.recalc_interval / 2) {
- LinkGraphSchedule::Instance()->JoinNext();
+ LinkGraphSchedule::instance.JoinNext();
}
}
Index: src/station_cmd.cpp
===================================================================
--- src/station_cmd.cpp (revision 27177)
+++ src/station_cmd.cpp (working copy)
@@ -57,6 +57,13 @@
#include "table/strings.h"
/**
+ * Static instance of FlowStat::SharesMap.
+ * Note: This instance is created on task start.
+ * Lazy creation on first usage results in a data race between the CDist threads.
+ */
+/* static */ const FlowStat::SharesMap FlowStat::empty_sharesmap;
+
+/**
* Check whether the given tile is a hangar.
* @param t the tile to of whether it is a hangar.
* @pre IsTileType(t, MP_STATION)
@@ -3515,7 +3522,7 @@
if (ge2.link_graph == INVALID_LINK_GRAPH) {
if (LinkGraph::CanAllocateItem()) {
lg = new LinkGraph(cargo);
- LinkGraphSchedule::Instance()->Queue(lg);
+ LinkGraphSchedule::instance.Queue(lg);
ge2.link_graph = lg->index;
ge2.node = lg->AddNode(st2);
} else {
@@ -3537,11 +3544,11 @@
if (ge1.link_graph != ge2.link_graph) {
LinkGraph *lg2 = LinkGraph::Get(ge2.link_graph);
if (lg->Size() < lg2->Size()) {
- LinkGraphSchedule::Instance()->Unqueue(lg);
+ LinkGraphSchedule::instance.Unqueue(lg);
lg2->Merge(lg); // Updates GoodsEntries of lg
lg = lg2;
} else {
- LinkGraphSchedule::Instance()->Unqueue(lg2);
+ LinkGraphSchedule::instance.Unqueue(lg2);
lg->Merge(lg2); // Updates GoodsEntries of lg2
}
}
@@ -3663,7 +3670,7 @@
if (ge.link_graph == INVALID_LINK_GRAPH) {
if (LinkGraph::CanAllocateItem()) {
lg = new LinkGraph(type);
- LinkGraphSchedule::Instance()->Queue(lg);
+ LinkGraphSchedule::instance.Queue(lg);
ge.link_graph = lg->index;
ge.node = lg->AddNode(st);
} else {