OpenTTD
linkgraphschedule.cpp
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
12 #include "../stdafx.h"
13 #include "linkgraphschedule.h"
14 #include "init.h"
15 #include "demands.h"
16 #include "mcf.h"
17 #include "flowmapper.h"
18 #include "../framerate_type.h"
19 
20 #include "../safeguards.h"
21 
28 
33 {
34  if (this->schedule.empty()) return;
35  LinkGraph *next = this->schedule.front();
36  LinkGraph *first = next;
37  while (next->Size() < 2) {
38  this->schedule.splice(this->schedule.end(), this->schedule, this->schedule.begin());
39  next = this->schedule.front();
40  if (next == first) return;
41  }
42  assert(next == LinkGraph::Get(next->index));
43  this->schedule.pop_front();
45  LinkGraphJob *job = new LinkGraphJob(*next);
46  job->SpawnThread();
47  this->running.push_back(job);
48  } else {
49  NOT_REACHED();
50  }
51 }
52 
57 {
58  if (this->running.empty()) return;
59  LinkGraphJob *next = this->running.front();
60  if (!next->IsFinished()) return;
61  this->running.pop_front();
62  LinkGraphID id = next->LinkGraphIndex();
63  delete next; // implicitly joins the thread
64  if (LinkGraph::IsValidID(id)) {
65  LinkGraph *lg = LinkGraph::Get(id);
66  this->Unqueue(lg); // Unqueue to avoid double-queueing recycled IDs.
67  this->Queue(lg);
68  }
69 }
70 
76 /* static */ void LinkGraphSchedule::Run(void *j)
77 {
78  LinkGraphJob *job = (LinkGraphJob *)j;
79  for (uint i = 0; i < lengthof(instance.handlers); ++i) {
80  instance.handlers[i]->Run(*job);
81  }
82 }
83 
89 {
90  for (JobList::iterator i = this->running.begin(); i != this->running.end(); ++i) {
91  (*i)->SpawnThread();
92  }
93 }
94 
98 /* static */ void LinkGraphSchedule::Clear()
99 {
100  for (JobList::iterator i(instance.running.begin()); i != instance.running.end(); ++i) {
101  (*i)->JoinThread();
102  }
103  instance.running.clear();
104  instance.schedule.clear();
105 }
106 
113 {
114  LinkGraph *lg;
115  FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(interval);
116  LinkGraphJob *lgj;
117  FOR_ALL_LINK_GRAPH_JOBS(lgj) lgj->ShiftJoinDate(interval);
118 }
119 
124 {
125  this->handlers[0] = new InitHandler;
126  this->handlers[1] = new DemandHandler;
127  this->handlers[2] = new MCFHandler<MCF1stPass>;
128  this->handlers[3] = new FlowMapper(false);
129  this->handlers[4] = new MCFHandler<MCF2ndPass>;
130  this->handlers[5] = new FlowMapper(true);
131 }
132 
137 {
138  this->Clear();
139  for (uint i = 0; i < lengthof(this->handlers); ++i) {
140  delete this->handlers[i];
141  }
142 }
143 
149 {
152  if (offset == 0) {
153  LinkGraphSchedule::instance.SpawnNext();
154  } else if (offset == _settings_game.linkgraph.recalc_interval / 2) {
156  LinkGraphSchedule::instance.JoinNext();
157  }
158 }
159 
160 
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:77
void Queue(LinkGraph *lg)
Queue a link graph for execution.
Declaration of initializing link graph handler.
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
void SpawnAll()
Start all threads in the running list.
void Unqueue(LinkGraph *lg)
Remove a link graph from the execution queue.
Link graph handler for MCF.
Definition: mcf.h:77
~LinkGraphSchedule()
Delete a link graph schedule and its handlers.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
virtual void Run(LinkGraphJob &job) const =0
Run the handler.
void ShiftDates(int interval)
Shift all dates by given interval.
Definition: linkgraph.cpp:54
void SpawnNext()
Start the next job in the schedule.
Declaration of Multi-Commodity-Flow solver.
void ShiftJoinDate(int interval)
Change the join date on date cheating.
Definition: linkgraphjob.h:293
void OnTick_LinkGraph()
Spawn or join a link graph job or compress a link graph if any link graph is due to do so...
RAII class for measuring simple elements of performance.
Map the path trees generated by the MCF solver into flows.
Definition: flowmapper.h:24
void JoinNext()
Join the next finished job, if available.
A connected component of a link graph.
Definition: linkgraph.h:40
void ShiftDates(int interval)
Shift all dates (join dates and edge annotations) of link graphs and link graph jobs by the number of...
Declaration of flow mapper; maps paths into flows at nodes.
uint Size() const
Get the current size of the component.
Definition: linkgraph.h:499
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
static LinkGraphSchedule instance
Static instance of LinkGraphSchedule.
uint16 recalc_interval
time (in days) between subsequent checks for link graphs to be calculated.
Declaration of demand calculating link graph handler.
Declaration of link graph schedule used for cargo distribution.
static void Run(void *j)
Run all handlers for the given Job.
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
void SpawnThread()
Spawn a thread if possible and run the link graph job in the thread.
Stateless, thread safe initialization hander.
Definition: init.h:12
bool IsFinished() const
Check if job is supposed to be finished.
Definition: linkgraphjob.h:281
ComponentHandler * handlers[6]
Handlers to be run for each job.
GraphList schedule
Queue for new jobs.
Stateless, thread safe demand hander.
Definition: demands.h:28
static void Clear()
Clear all link graphs and jobs from the schedule.
LinkGraphSchedule()
Create a link graph schedule and initialize its handlers.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:216
LinkGraphID LinkGraphIndex() const
Get the ID of the underlying link graph.
Definition: linkgraphjob.h:330
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
int32 Date
The type to store our dates in.
Definition: date_type.h:16
static const uint SPAWN_JOIN_TICK
Tick when jobs are spawned or joined every day.
JobList running
Currently running jobs.
Date _date
Current date in days (day counter)
Definition: date.cpp:28
LinkGraphSettings linkgraph
settings for link graph calculations
Time spent waiting for link graph background jobs.
Class for calculation jobs to be run on link graphs.
Definition: linkgraphjob.h:31