LocalScheduler.h 9.36 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 *		RAVEN Interface
 *
 *		(c) Copyright Institute of Technical Acoustic (ITA)
 *			RWTH Aachen University (http://www.akustik.rwth-aachen.de)
 *
 *  ---------------------------------------------------------------------------------
 *
 *    File:			R_RavenLocalScheduler.h
 *
 *    Purpose:		Raven simulation scheduler, that is running local simulation instances
 *					using threads and manages tasks based on priority and desired update rates
 *
 *    Author(s):	Jonas Stienen (stienen@akustik.rwth-aachen.de)
 *
 *  ---------------------------------------------------------------------------------
 */
  
// $Id: RavenTest.cpp 2732 2012-06-26 13:38:17Z stienen $

#ifndef __R_RAVEN_LOCAL_SCHEDULER_H__
#define __R_RAVEN_LOCAL_SCHEDULER_H__

// API includes
Pascal Palenda's avatar
Pascal Palenda committed
25
#include <ITASimulationScheduler/Definitions.h>
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

// Raven includes
#include <ITASimulationScheduler//Raven/R_Raven.h>

// ITA includes
#include <ITAAtomicPrimitives.h>
#include <ITADataLog.h>
#include <ITASampleFrame.h>
#include <ITAStopWatch.h>

// Vista includes
#include <VistaInterProcComm/Concurrency/VistaThreadEvent.h>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <VistaInterProcComm/Concurrency/VistaPriority.h>

// 3rdParty includes
#include <tbb/concurrent_queue.h>

// STL includes
#include <assert.h>
#include <list>
#include <vector>

49
namespace ITASimulationScheduler
50
51
{

52
53
54
55
56
57
58
59
60
61
	//! Lokaler Scheduler fr Raven-Simulationsauftrge
	/**
	  * Dieser lokal arbeitende Scheduler erzeugt mehrere Threads fr Raven-Simulatoren und verteilt
	  * eingehende Tasks auf diese. Dabei arbeitet er so, dass die Threads mit unterschiedlichen
	  * Priorisierungen laufen und jeweils unterschiedliche Simulationsauftrge abarbeiten (DS, DS+IS, IS und RT).
	  * Andere Typen sind nicht erlaubt, und die Anzahl der verfgbaren Entitten (Receiver, Sources, Portals)
	  * hngt von der Einstellung der Raven-Simulatoren (CRavenSimulator) ab.
	  * Der lokale Scheduler verwirft smtliche Tasks, die nicht abgearbeitet werden konnten und von einem
	  * neuen Task unter folgenden auflagen verdngt wurden:
	  *
Pascal Palenda's avatar
Pascal Palenda committed
62
	  *		1. Exakt identische Konfiguration (CConfig)
63
	  *		2. Identischer Auftragstyp  (DS, DS+ER, ER oder DD)
Pascal Palenda's avatar
Pascal Palenda committed
64
	  *		3. Gleiche Szene (CScene), d.h. smtliche Entitten identisch, aber mglicherweise unterschiedlicher State (CRaven*State)
65
66
67
68
69
	  *
	  * \todo	Eventuell den Scheduler so einstellbar machen, dass er sich auch anders verhlt, z.B. NIE verdrngt. Dies
	  *			knnte dann sinnvoll sein, wenn man den Scheduler als "Task-Queue" verwendet, um z.B. Trajektorien abzufahren und
	  *			Impulsantworten zu generieren.
	  */
Pascal Palenda's avatar
Pascal Palenda committed
70
	class ITA_SIMULATION_SCHEDULER_API CLocalScheduler : public ISimulationSchedulerInterface, public VistaThreadLoop
71
72
	{
	public:
73
74
75

		//! Scheduler configuration
		class ITA_SIMULATION_SCHEDULER_API CConfiguration
76
77
		{
		public:
78
79
			//! Thread configuration
			class ITA_SIMULATION_SCHEDULER_API CThreadConfiguration
80
			{
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
			public:

				//! Process task assignment
				enum
				{
					TIMEOUT = 0,	//!< Update task assignment using a timeout
					EVENTSYNC,		//!< Update task assignment when added  (may use entire ressources)
					CONTINUOUS		//!< Update tasks continuously (uses entire ressources)
				};

				int iTaskProcessingMode;	//!< One of \TaskAssignmentProcessing
				int iFieldOfDuty;			//!< Field of duty for this thread (DS, ER, DD)
				float fUpdateRate;			//!< Desired update rate for this thread in Hz
				int iPriority;				//!< Thread priority, careful with this parameter!
				std::string sRavenDataBasePath; //!< Raven data base path
96
97
			};

98
99
100
101
			std::string sRavenDataBasePath; //!< Local path to RAVEN data, can be absolute or relative to executable
			std::vector< CThreadConfiguration > voThreads; //!< List of thread configurations

			std::string ToString() const;
102
103
		};

104
105
106
107
108
109
110
		//! Constructor with configuration
		/**
		  * Creates a scheduler based on given configuration
		  *
		  * \param oConf Local scheduler configuration, see \Configuration
		  *
		  */
Pascal Palenda's avatar
Pascal Palenda committed
111
		CLocalScheduler(const CConfiguration& oConf);
112

113
		//! Destructor
Pascal Palenda's avatar
Pascal Palenda committed
114
		virtual ~CLocalScheduler();
115

116
117
118
119
120
		//! Alles RAVEN-artige intern abrumen und neu aufsetzen
		/**
		  * \note Non-reentrant! Es darf wrend dieses Aufrufs keine andere Funktion parallel betreten werden
		  */
		virtual void Reset();
121

122
123
124
125
		//! Laden der Geometrien aus einer Scene
		/**
		  * \note Non-reentrant! Es darf wrend dieses Aufrufs keine andere Funktion parallel betreten werden
		  */
Pascal Palenda's avatar
Pascal Palenda committed
126
		virtual void AddTask(CSimulationTask* pTask);
127

128
129
		//! Preload geometry
		virtual void LoadScene(const std::string&);
130

Pascal Palenda's avatar
Pascal Palenda committed
131
132
		virtual void HandleTaskFinished(CSimulationTask* pTask, CSimulationResult* pResult, int iErrorcode);
		virtual void HandleTaskDiscarded(CSimulationTask* pTask);
133

Pascal Palenda's avatar
Pascal Palenda committed
134
135
		virtual bool AttachSimulationResultHandler(ISimulationSchedulerResultHandler*);
		virtual bool DetachSimulationResultHandler(ISimulationSchedulerResultHandler*);
136

Pascal Palenda's avatar
Pascal Palenda committed
137
		virtual bool GetProfilerStatus(ISimulationSchedulerInterface::CProfiler& oStatus);
138

139
140
		// --= Schnittstelle "VistaCoreThread" =--
		virtual bool LoopBody();
141

142
143
144
145
		class CSimulationThread : public VistaThreadLoop
		{
		public:
			//! Erzeugt einen eigenstndigen Simulationsthread mit einer Raven-Instanz
Pascal Palenda's avatar
Pascal Palenda committed
146
			CSimulationThread(CLocalScheduler* pScheduler, const CConfiguration::CThreadConfiguration& oConf);
147

148
			virtual ~CSimulationThread();
149

150
151
			//! Gibt true zurck, wenn kein Task bearbeitet wird
			virtual bool IsIdle();
152

153
154
			//! Gibt true zurck, wenn die Scene geladen ist
			virtual bool IsSceneLoaded() const;
155

156
157
158
159
			//! Gibt den aktuellen Task oder NULL (Idle) zurck
			/**
			  * \note Es gibt keine Garantie, dass der Task weiterhin existiert
			  */
Pascal Palenda's avatar
Pascal Palenda committed
160
			virtual CSimulationTask* GetCurrentTask() const;
161

162
163
			//! Task retrieval loop
			virtual bool LoopBody();
164

165
			//! Performs compute of given task
Pascal Palenda's avatar
Pascal Palenda committed
166
			virtual void Compute(CSimulationTask* pTask);
167

168
169
			//! Preloads geometry
			virtual void LoadScene(const std::string& sFilename);
170

171
172
			//! Performs reset of instance
			virtual void Reset();
173

174
175
176
177
178
			//! Get configuration
			const CConfiguration::CThreadConfiguration& GetConfiguration() const;

		protected:
			ITAStopWatch swCompute;
179

180
181
		private:
			VistaThreadEvent m_evTrigger;
Pascal Palenda's avatar
Pascal Palenda committed
182
183
184
			ITAAtomicPtr< CSimulationTask > m_pTask;
			CLocalScheduler* m_pParentScheduler;
			ISimulationInterface* m_pRavenSimulator;
185
186
187
188
189
190
191
192
			ITAAtomicBool m_bSceneLoaded;
			ITAAtomicBool m_bStop;
			ITAAtomicBool m_bIndicateStop;
			ITAAtomicBool m_bReset;
			ITASampleFrame m_oLatestResult;

			CConfiguration::CThreadConfiguration m_oConf;

Pascal Palenda's avatar
Pascal Palenda committed
193
			friend class CLocalScheduler;
194
		};
195
196
197

	protected:

Pascal Palenda's avatar
Pascal Palenda committed
198
		typedef std::list< CSimulationTask* > TaskList;
199
200
201
		typedef TaskList::iterator TaskListIt;
		typedef TaskList::const_iterator TaskListCit;

Pascal Palenda's avatar
Pascal Palenda committed
202
		tbb::concurrent_queue< CSimulationTask* > m_qpNewTasks; // bergabestruktur (non-blocking)
203
204
205
206
207
208
209
210
211
212
213
214
215
		TaskList m_lDSTasks;	// Interne Aufgabenlisten Direktschall
		TaskList m_lERTasks;	// Interne Aufgabenlisten Image Sources
		TaskList m_lDDRTTasks;	// Interne Aufgabenlisten Ray Tracing
		TaskList m_lDDARTasks;	// Interne Aufgabenlisten Artificial Reverb

		CConfiguration m_oConf;

		// Threads mit Raven Instanzen
		typedef std::vector< CSimulationThread* > ThreadList;
		typedef ThreadList::iterator ThreadListIt;
		typedef ThreadList::const_iterator ThreadListCit;

		ThreadList m_lpSimThreads;
216
		VistaThreadEvent m_evTrigger;
217
218
219

		ITAAtomicBool m_bStopIndicated, m_bStopAck, m_bResetIndicated, m_bResetAck;

Pascal Palenda's avatar
Pascal Palenda committed
220
		ISimulationSchedulerInterface::CProfiler m_oProfiler;
221
222
223
224
225
226
		ITAStopWatch m_swCompute;
		double m_dDurationOfDwellFinishedSumDS, m_dDurationOfDwellDiscardedSumDS;
		double m_dDurationOfDwellFinishedSumERIS, m_dDurationOfDwellDiscardedSumERIS;
		double m_dDurationOfDwellFinishedSumDDRT, m_dDurationOfDwellDiscardedSumDDRT;
		double m_dDurationOfDwellFinishedSumDDAR, m_dDurationOfDwellDiscardedSumDDAR;

Pascal Palenda's avatar
Pascal Palenda committed
227
		std::list< ISimulationSchedulerResultHandler* > m_lpTaskHandler; //!< Liste der Task-Handler
228
229
230

		// Lscht alle Auftrge mit Quelle/Hrer aus einer Auftragsliste und ersetzt die
		// alte Position mit dem neuen Auftrag
Pascal Palenda's avatar
Pascal Palenda committed
231
		void FilterAndReplaceTasks(TaskList&, CSimulationTask*);
232
233

		friend class CSimulationThread;
234
235
	};

236
	//! Schnittstelle zur Rckmeldung ber den Zustand von Simulationsaufgaben implementieren
Pascal Palenda's avatar
Pascal Palenda committed
237
	class ITA_SIMULATION_SCHEDULER_API CSimulationSchedulerTaskHandler : public ISimulationSchedulerResultHandler
238
239
	{
	public:
Pascal Palenda's avatar
Pascal Palenda committed
240
241
242
243
		virtual ~CSimulationSchedulerTaskHandler() {};
		virtual int PreTaskStart(ISimulationSchedulerInterface*, CSimulationTask*) { return ISimulationSchedulerResultHandler::COMPUTE_TASK; };
		virtual int PostTaskFinished(ISimulationSchedulerInterface*, const CSimulationTask*, CSimulationResult*) { return ISimulationSchedulerResultHandler::DELETE_TASK; };
		virtual int PostTaskDiscarded(ISimulationSchedulerInterface*, const CSimulationTask*) { return ISimulationSchedulerResultHandler::DELETE_TASK; };
244
245
246
	};

	//! Scheduler Result Handler that stores results to the hard drive
Pascal Palenda's avatar
Pascal Palenda committed
247
	class ITA_SIMULATION_SCHEDULER_API CSimulationResultDumper : public CSimulationSchedulerTaskHandler
248
249
250
251
	{
	public:
		CSimulationResultDumper(const std::string& sOutputDataPath);
		virtual ~CSimulationResultDumper() {};
252

Pascal Palenda's avatar
Pascal Palenda committed
253
254
		int PostTaskFinished(ISimulationSchedulerInterface*, const CSimulationTask*, CSimulationResult*);
		int PostTaskDiscarded(ISimulationSchedulerInterface*, const CSimulationTask*);
255

256
257
258
259
260
261
262
263
		unsigned int GetNumTasksFinished() const;
		unsigned int GetNumTasksDiscarded() const;
		unsigned int GetNumTasksReceived() const;
	private:
		unsigned int m_uiCountFinished, m_uiCountDiscarded;
		std::string m_sOutputDataPath;

	};
264

265
}
266
267

#endif // __R_RAVEN_LOCAL_SCHEDULER_H__