OpenTTD

linkgraphschedule.cpp
Go to the documentation of this file.
1 /* $Id: linkgraphschedule.cpp 27178 2015-03-07 18:27:01Z frosch $ */
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
19 #include "../safeguards.h"
20
26 /* static */ LinkGraphSchedule LinkGraphSchedule::instance;
27
31 void LinkGraphSchedule::SpawnNext()
32 {
33 if (this->schedule.empty()) return;
34 LinkGraph *next = this->schedule.front();
35 LinkGraph *first = next;
36 while (next->Size() < 2) {
37 this->schedule.splice(this->schedule.end(), this->schedule, this->schedule.begin());
38 next = this->schedule.front();
39 if (next == first) return;
40 }
41 assert(next == LinkGraph::Get(next->index));
42 this->schedule.pop_front();
43 if (LinkGraphJob::CanAllocateItem()) {
44 LinkGraphJob *job = new LinkGraphJob(*next);
45 job->SpawnThread();
46 this->running.push_back(job);
47 } else {
48 NOT_REACHED();
49 }
50 }
51
55 void LinkGraphSchedule::JoinNext()
56 {
57 if (this->running.empty()) return;
58 LinkGraphJob *next = this->running.front();
59 if (!next->IsFinished()) return;
60 this->running.pop_front();
61 LinkGraphID id = next->LinkGraphIndex();
62 delete next; // implicitly joins the thread
63 if (LinkGraph::IsValidID(id)) {
64 LinkGraph *lg = LinkGraph::Get(id);
65 this->Unqueue(lg); // Unqueue to avoid double-queueing recycled IDs.
66 this->Queue(lg);
67 }
68 }
69
75 /* static */ void LinkGraphSchedule::Run(void *j)
76 {
77 LinkGraphJob *job = (LinkGraphJob *)j;
78 for (uint i = 0; i < lengthof(instance.handlers); ++i) {
79 instance.handlers[i]->Run(*job);
80 }
81 }
82
87 void LinkGraphSchedule::SpawnAll()
88 {
89 for (JobList::iterator i = this->running.begin(); i != this->running.end(); ++i) {
90 (*i)->SpawnThread();
91 }
92 }
93
97 /* static */ void LinkGraphSchedule::Clear()
98 {
99 for (JobList::iterator i(instance.running.begin()); i != instance.running.end(); ++i) {
100 (*i)->JoinThread();
101 }
102 instance.running.clear();
103 instance.schedule.clear();
104 }
105
111 void LinkGraphSchedule::ShiftDates(int interval)
112 {
113 LinkGraph *lg;
114 FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(interval);
115 LinkGraphJob *lgj;
116 FOR_ALL_LINK_GRAPH_JOBS(lgj) lgj->ShiftJoinDate(interval);
117 }
118
122 LinkGraphSchedule::LinkGraphSchedule()
123 {
124 this->handlers[0] = new InitHandler;
125 this->handlers[1] = new DemandHandler;
126 this->handlers[2] = new MCFHandler<MCF1stPass>;
127 this->handlers[3] = new FlowMapper(false);
128 this->handlers[4] = new MCFHandler<MCF2ndPass>;
129 this->handlers[5] = new FlowMapper(true);
130 }
131
135 LinkGraphSchedule::~LinkGraphSchedule()
136 {
137 this->Clear();
138 for (uint i = 0; i < lengthof(this->handlers); ++i) {
139 delete this->handlers[i];
140 }
141 }
142
147 void OnTick_LinkGraph()
148 {
149 if (_date_fract != LinkGraphSchedule::SPAWN_JOIN_TICK) return;
150 Date offset = _date % _settings_game.linkgraph.recalc_interval;
151 if (offset == 0) {
152 LinkGraphSchedule::instance.SpawnNext();
153 } else if (offset == _settings_game.linkgraph.recalc_interval / 2) {
154 LinkGraphSchedule::instance.JoinNext();
155 }
156 }
157
158
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:77
LinkGraphSchedule::Queue
void Queue(LinkGraph *lg)
Queue a link graph for execution.
Definition: linkgraphschedule.h:68
init.h
Declaration of initializing link graph handler.
Pool::PoolItem<&_link_graph_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
LinkGraphSchedule::SpawnAll
void SpawnAll()
Start all threads in the running list.
Definition: linkgraphschedule.cpp:87
LinkGraphSchedule::Unqueue
void Unqueue(LinkGraph *lg)
Remove a link graph from the execution queue.
Definition: linkgraphschedule.h:78
MCFHandler
Link graph handler for MCF.
Definition: mcf.h:77
LinkGraphSchedule::~LinkGraphSchedule
~LinkGraphSchedule()
Delete a link graph schedule and its handlers.
Definition: linkgraphschedule.cpp:135
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
ComponentHandler::Run
virtual void Run(LinkGraphJob &job) const =0
Run the handler.
LinkGraph::ShiftDates
void ShiftDates(int interval)
Shift all dates by given interval.
Definition: linkgraph.cpp:54
LinkGraphSchedule
Definition: linkgraphschedule.h:38
LinkGraphSchedule::SpawnNext
void SpawnNext()
Start the next job in the schedule.
Definition: linkgraphschedule.cpp:31
mcf.h
Declaration of Multi-Commodity-Flow solver.
LinkGraphJob::ShiftJoinDate
void ShiftJoinDate(int interval)
Change the join date on date cheating.
Definition: linkgraphjob.h:293
OnTick_LinkGraph
void OnTick_LinkGraph()
Spawn or join a link graph job or compress a link graph if any link graph is due to do so...
Definition: linkgraphschedule.cpp:147
FlowMapper
Map the path trees generated by the MCF solver into flows.
Definition: flowmapper.h:24
LinkGraphSchedule::JoinNext
void JoinNext()
Join the next finished job, if available.
Definition: linkgraphschedule.cpp:55
LinkGraph
A connected component of a link graph.
Definition: linkgraph.h:40
LinkGraphSchedule::ShiftDates
void ShiftDates(int interval)
Shift all dates (join dates and edge annotations) of link graphs and link graph jobs by the number of...
Definition: linkgraphschedule.cpp:111
flowmapper.h
Declaration of flow mapper; maps paths into flows at nodes.
LinkGraph::Size
uint Size() const
Get the current size of the component.
Definition: linkgraph.h:499
_date_fract
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
LinkGraphSchedule::instance
static LinkGraphSchedule instance
Static instance of LinkGraphSchedule.
Definition: linkgraphschedule.h:54
LinkGraphSettings::recalc_interval
uint16 recalc_interval
time (in days) between subsequent checks for link graphs to be calculated.
Definition: settings_type.h:496
demands.h
Declaration of demand calculating link graph handler.
linkgraphschedule.h
Declaration of link graph schedule used for cargo distribution.
LinkGraphSchedule::Run
static void Run(void *j)
Run all handlers for the given Job.
Definition: linkgraphschedule.cpp:75
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
LinkGraphJob::SpawnThread
void SpawnThread()
Spawn a thread if possible and run the link graph job in the thread.
Definition: linkgraphjob.cpp:62
InitHandler
Stateless, thread safe initialization hander.
Definition: init.h:12
LinkGraphJob::IsFinished
bool IsFinished() const
Check if job is supposed to be finished.
Definition: linkgraphjob.h:281
LinkGraphSchedule::handlers
ComponentHandler * handlers[6]
Handlers to be run for each job.
Definition: linkgraphschedule.h:47
LinkGraphSchedule::schedule
GraphList schedule
Queue for new jobs.
Definition: linkgraphschedule.h:48
DemandHandler
Stateless, thread safe demand hander.
Definition: demands.h:28
LinkGraphSchedule::Clear
static void Clear()
Clear all link graphs and jobs from the schedule.
Definition: linkgraphschedule.cpp:97
LinkGraphSchedule::LinkGraphSchedule
LinkGraphSchedule()
Create a link graph schedule and initialize its handlers.
Definition: linkgraphschedule.cpp:122
Pool::PoolItem<&_link_graph_job_pool >::CanAllocateItem
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
LinkGraphJob::LinkGraphIndex
LinkGraphID LinkGraphIndex() const
Get the ID of the underlying link graph.
Definition: linkgraphjob.h:330
Pool::PoolItem<&_link_graph_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
Date
int32 Date
The type to store our dates in.
Definition: date_type.h:16
LinkGraphSchedule::SPAWN_JOIN_TICK
static const uint SPAWN_JOIN_TICK
Tick when jobs are spawned or joined every day.
Definition: linkgraphschedule.h:53
LinkGraphSchedule::running
JobList running
Currently running jobs.
Definition: linkgraphschedule.h:49
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:28
GameSettings::linkgraph
LinkGraphSettings linkgraph
settings for link graph calculations
Definition: settings_type.h:554
LinkGraphJob
Class for calculation jobs to be run on link graphs.
Definition: linkgraphjob.h:31