00001 /** @file Scheduler.h 00002 * @author Gabor Madl 00003 * @date Created 02/2005 00004 * @brief Scheduler model implementation. 00005 * 00006 * 00007 * ================================================================= 00008 * DREAM License v2.0 00009 * 00010 * DREAM - Distributed Real-time Embedded Analysis Method 00011 * http://dre.sourceforge.net. 00012 * Copyright (c) 2005-2007 Gabor Madl, All Rights Reserved. 00013 * 00014 * This file is part of DREAM. 00015 * 00016 * DREAM is free software; you can redistribute it and/or modify it 00017 * under the terms of the GNU General Public License version 2 as 00018 * published by the Free Software Foundation. No future versions of 00019 * the GPL license may be automatically applied to DREAM. It is in 00020 * the sole discretion of the copyright holder to determine whether 00021 * DREAM may be released under a different license or terms. There 00022 * are no restrictions on the use of DREAM for any purpose. 00023 * 00024 * DREAM is distributed in the hope that it will be useful, 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00027 * GNU General Public License for more details. 00028 * 00029 * You should have received a copy of the GNU General Public License 00030 * along with this program; if not, write to the Free Software 00031 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00032 * MA 02110-1301, USA. 00033 * 00034 * By submitting comments, suggestions, code, code snippets, 00035 * techniques (including that of usage), and algorithms, submitters 00036 * acknowledge that they have the right to do so, that any such 00037 * submissions are given freely and unreservedly, and that they 00038 * waive any claims to copyright or ownership. In addition, 00039 * submitters acknowledge that any such submission might become 00040 * part of the copyright maintained on the overall body of code, 00041 * which comprises DREAM. By making a submission, submitter agrees 00042 * to these terms. Furthermore, submitters acknowledge that the 00043 * incorporation or modification of such submissions is entirely 00044 * at the discretion of the moderators of the DREAM project. 00045 * 00046 * DREAM links to the Libxml2 third party library. Please see 00047 * COPYING-libxml for the copyright information of Libxml2. 00048 * ================================================================= 00049 */ 00050 00051 #ifndef DREAM_SCHEDULER 00052 #define DREAM_SCHEDULER 00053 00054 namespace DREAM 00055 { 00056 class Scheduler; 00057 class System; 00058 } 00059 00060 #include "Task.h" 00061 #include "Thread.h" 00062 #include "Exception.h" 00063 #include "System.h" 00064 00065 namespace DREAM 00066 { 00067 00068 struct take_transitions; 00069 00070 /** The base class for QoS properties. 00071 * The base class that contains QoS properties for the Schedulers. The current implementation captures voltage- and frequency-scaling. 00072 * @todo Implement dynamic power modeling using this class. 00073 */ 00074 class QoSLevel 00075 { 00076 public: 00077 /** Constructor for the class. 00078 * @param speed is the speed corresponding to the QoS-level. 00079 * @param power is the power level corresponding to the QoS-level. 00080 */ 00081 QoSLevel (const double speed, const double power); 00082 00083 /** Destructor. */ 00084 ~QoSLevel () {}; 00085 00086 /** Returns the speed parameter. */ 00087 double speed () const; 00088 00089 /** Returns the power parameter. */ 00090 double power () const; 00091 00092 protected: 00093 /** The speed corresponding to the QoS-level. */ 00094 const double speed_; 00095 00096 /** The power level corresponding to the QoS-level. */ 00097 const double power_; 00098 }; 00099 00100 /** Basic Scheduler model. 00101 * The base class of the Scheduler implementation in the DRE Semantic Domain. 00102 */ 00103 class Scheduler 00104 { 00105 public: 00106 /** Constructor. */ 00107 Scheduler (const std::string& id, DREAM::System* system_ptr, uint CPUs = 1); 00108 00109 /** Destructor. */ 00110 virtual ~Scheduler (); 00111 00112 /** Puts a Node into the Scheduler pool - thread_map_. 00113 * This function implements the mapping of Nodes to a platform processor in the 00114 * DRE Semantic Domain. The scheduler will know about this Node and manage its execution. 00115 * @param node_ptr is a pointer to the Node which will be put in the Scheduler pool - thread_map_. 00116 * @param priority specifies the priority of the Thread to which the Node will be added. 00117 */ 00118 virtual void add (DREAM::Node* node_ptr, uint priority) 00119 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00120 throw (DREAM::Exception) 00121 #endif 00122 ; 00123 00124 /** Adds a Task in the error AVL tree - error_avltree_. 00125 * @param task_ptr is a pointer to the Task which will be put in the error AVL tree - error_avltree_. 00126 */ 00127 virtual void add_error (DREAM::Task* task_ptr); 00128 00129 /** Adds a Thread into the Scheduler pool - thread_map_. 00130 * This function implements the mapping of Threads to a platform processor in the 00131 * DRE Semantic Domain. The scheduler will know about this Thread and manage its execution. 00132 * @param thread_ptr is a pointer to the Thread which will be put in the Scheduler pool - thread_map_. 00133 */ 00134 virtual void add_thread (DREAM::Thread* thread_ptr) 00135 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00136 throw (DREAM::Exception) 00137 #endif 00138 ; 00139 00140 /** Returns the number of CPUs managed by the Scheduler. 00141 * It returns 0 by default because non-concurrent Schedulers do not need a CPU, it is only used in the DREAM implementation. 00142 */ 00143 virtual uint CPUs () const; 00144 00145 /** Frees an available CPU (Resource) of the Scheduler. */ 00146 virtual void freeCPU () 00147 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00148 throw (DREAM::Exception) 00149 #endif 00150 ; 00151 00152 /** Returns a Thread from the list. 00153 * @param priority specifies the priority of the Thread to be returned. 00154 * @return pointer to the Thread. 00155 */ 00156 virtual DREAM::Thread* get_thread (uint priority) const 00157 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00158 throw (DREAM::Exception) 00159 #endif 00160 ; 00161 00162 /** Generic Schedulers do not have priority lanes. 00163 * Inherited classes may implement this feature. 00164 */ 00165 virtual bool highestpriority (const DREAM::Node* node_ptr) const 00166 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00167 throw (DREAM::Exception) 00168 #endif 00169 ; 00170 00171 /** Returns the name of the Scheduler. 00172 * @return The id_ of the Scheduler. 00173 */ 00174 virtual std::string id () const; 00175 00176 /** Generic Schedulers do not have priority lanes. 00177 * Inherited classes may implement this feature. 00178 */ 00179 virtual bool lowestpriority (const DREAM::Node* node_ptr) const 00180 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00181 throw (DREAM::Exception) 00182 #endif 00183 ; 00184 00185 /** Return the time of the next event generated by the thread_map_. */ 00186 virtual double next_event (bool deterministic) const 00187 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00188 throw (DREAM::Exception) 00189 #endif 00190 ; 00191 00192 /** The generic scheduler does not implement this function. Throws Exception. */ 00193 virtual bool nonpreemptive () const 00194 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00195 throw (DREAM::Exception) 00196 #endif 00197 ; 00198 00199 /** Returns the power level cooresponding to the current QoS level. */ 00200 virtual double power () const; 00201 00202 /** Adds a QoS level to the Scheduler. 00203 * Note that the Scheduler has the ownership of the QoSLevel data structure and it manages its lifecycle. 00204 * @param qos_ptr is the pointer to the QoSLevel data structure. 00205 */ 00206 virtual void qos_add (DREAM::QoSLevel* qos_ptr); 00207 00208 /** Returns the two QoSLevels closest to the parameter power level, one consuming less, the other consuming more than the parameter. 00209 * If the parameter power level can be found then both the low and the high values will refer to the optimal QoSLevel object. 00210 * If not, the two closest mathes are obtained. We build on the assumption that faster QoS levels involve larger power levels. 00211 * This case is ture in general as power is in a squared relation with speed. Special cases might be implemented later... 00212 * @param power is the parameter power level for which we would like to find the QoSLevel objects. 00213 * @param low is set to the fastest speed that is not faster than the speed parameter. 00214 * @param high is set to the slowest speed that is not slower than the speed parameter. 00215 */ 00216 virtual void qos_power (const double power, DREAM::QoSLevel* low, DREAM::QoSLevel* high) 00217 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00218 throw (DREAM::Exception) 00219 #endif 00220 ; 00221 00222 /** Returns the two QoSLevels closest to the parameter speed, one being slower the other being faster than the parameter. 00223 * If the parameter speed can be found then both the low and the high values will refer to the optimal QoSLevel object. If not, the two closest mathes are obtained. 00224 * @param speed is the parameter speed for which we would like to find the QoSLevel objects. 00225 * @param low is set to the fastest speed that is not faster than the speed parameter. 00226 * @param high is set to the slowest speed that is not slower than the speed parameter. 00227 */ 00228 virtual void qos_speed (const double speed, DREAM::QoSLevel* low, DREAM::QoSLevel* high) 00229 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00230 throw (DREAM::Exception) 00231 #endif 00232 ; 00233 00234 /** Removes a Node from the Scheduler pool - thread_map_. 00235 * This function is called when redeploying Nodes to different platform processors. 00236 * @param node_ptr is a pointer to the Node which will be removed from the Scheduler pool - thread_map_. 00237 * @param priority specifies the priority of the Thread from which the Node will be deleted. 00238 */ 00239 virtual void erase (DREAM::Node* node_ptr, uint priority) 00240 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00241 throw (DREAM::Exception) 00242 #endif 00243 ; 00244 00245 /** Resets Nodes managed by the scheduler (when restarting the simulation). */ 00246 virtual void reset (); 00247 00248 /** Generic Schedulers do not schedule. 00249 * Inherited classes may implement this feature. 00250 */ 00251 virtual void schedule (bool deterministic) 00252 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00253 throw (DREAM::Exception) 00254 #endif 00255 ; 00256 00257 /** Generic Schedulers do not simulate. 00258 * Inherited classes may implement this feature. 00259 */ 00260 virtual void simulate (bool verbose, bool deterministic = false) 00261 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00262 throw (DREAM::Exception) 00263 #endif 00264 ; 00265 00266 /** Returns the speed corresponding to the current QoS level. */ 00267 virtual double speed () const; 00268 00269 /** Stops the Scheduler. */ 00270 virtual void stop (); 00271 00272 /** Returns the System that owns the Scheduler. */ 00273 virtual const DREAM::System* system () const 00274 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00275 throw (DREAM::Exception) 00276 #endif 00277 ; 00278 00279 /** Returns the System that owns the Scheduler. */ 00280 virtual DREAM::System* system () 00281 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00282 throw (DREAM::Exception) 00283 #endif 00284 ; 00285 00286 /** Takes transitions in every Thread in the thread_map_. */ 00287 virtual void take_transitions () 00288 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00289 throw (DREAM::Exception) 00290 #endif 00291 ; 00292 00293 /** Returns the Thread map thread_map_. */ 00294 virtual const DREAM::THREAD_MAP* thread_map () const; 00295 00296 /** Return the size of the thread pool - thread_map_. */ 00297 virtual uint threadpoolsize () const; 00298 00299 /** Returns the (global) time of the Scheduler. */ 00300 virtual double time () const 00301 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00302 throw (DREAM::Exception) 00303 #endif 00304 ; 00305 00306 /** Time jump. 00307 * @param time_step specifies the time step to be made. 00308 */ 00309 virtual void time_step (double time_step) 00310 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00311 throw (DREAM::Exception) 00312 #endif 00313 ; 00314 00315 /** Function used to output info. 00316 * @param output is the std::string to be displayed. 00317 */ 00318 virtual void trace (const std::string& output) const; 00319 00320 /** Specifies whether simulation messages will be supressed or not. */ 00321 virtual void verbose (bool value); 00322 00323 /** This function builds the error list. 00324 * The function is used by genetic algorithms. 00325 * @param task_avltree stores the list of Nodes from the Scheduler error list. 00326 */ 00327 virtual void visitor_error_avltree (DREAM::TASK_AVLTREE* task_avltree) 00328 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00329 throw (DREAM::Exception) 00330 #endif 00331 ; 00332 00333 /** This function is part of the IF system description generator. 00334 * @param task_map stores the Task pointers. 00335 * @param channel_map stores the Channel pointers. 00336 * @param timer_map stores the Timer pointers. 00337 * @param f_stream is the output stream to be written to. 00338 */ 00339 virtual void visitor_if (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map, std::ofstream& f_stream) 00340 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00341 throw (DREAM::Exception) 00342 #endif 00343 ; 00344 00345 /** This function fills the IDs (names) of tasks, channels and timers to the parameter lists. 00346 * The function is used to generate output for model checkers. 00347 * @param task_map stores the Task pointers. 00348 * @param channel_map stores the Channel pointers. 00349 * @param timer_map stores the Timer pointers. 00350 */ 00351 virtual void visitor_map (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, 00352 DREAM::NODE_MAP* timer_map) 00353 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00354 throw (DREAM::Exception) 00355 #endif 00356 ; 00357 00358 /** This function builds the task list for manipulation. 00359 * The function is used by genetic algorithms. 00360 * @param task_avltree stores the Task pointers. 00361 */ 00362 virtual void visitor_task_avltree (DREAM::TASK_AVLTREE* task_avltree) 00363 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00364 throw (DREAM::Exception) 00365 #endif 00366 ; 00367 00368 /** This function updates task values in the system. 00369 * The function is used by genetic algorithms. 00370 * @param task_avltree stores the Task pointers. 00371 */ 00372 virtual void visitor_update_task_avltree (DREAM::TASK_AVLTREE* task_avltree) 00373 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00374 throw (DREAM::Exception) 00375 #endif 00376 ; 00377 00378 /** This function is part of the Uppaal system description generator. 00379 * @param task_map stores the Task pointers. 00380 * @param channel_map stores the Channel pointers. 00381 * @param timer_map stores the Timer pointers. 00382 * @param f_stream is the output stream to be written to. 00383 */ 00384 virtual void visitor_uppaal (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, 00385 DREAM::NODE_MAP* timer_map, std::ofstream& f_stream) 00386 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00387 throw (DREAM::Exception) 00388 #endif 00389 ; 00390 00391 protected: 00392 00393 #ifndef DREAM_NON_EXECUTING_TASKS 00394 /** Puts non-executed nodes in the error AVL tree. 00395 * @param node_map specifies the map which is checked for non-executed Nodes. 00396 */ 00397 virtual void check_executed (const DREAM::NODE_MAP* node_map); 00398 #endif 00399 00400 /** Flag to signal end of event loop. */ 00401 bool active_; 00402 00403 /** The number of available Processors (Resources) which can execute Threads. */ 00404 uint availableCPUs_; 00405 00406 /** The number of Processors (Resources) which can execute Threads. */ 00407 uint CPUs_; 00408 00409 /** The name of the Scheduler. */ 00410 std::string id_; 00411 00412 /** Queue for Tasks that missed the deadline etc. */ 00413 DREAM::TASK_AVLTREE error_avltree_; 00414 00415 /** List of all the Threads managed by the Scheduler - the Scheduler thread pool. */ 00416 DREAM::THREAD_MAP thread_map_; 00417 00418 /** Clock for the Scheduler. */ 00419 double time_; 00420 00421 /** Specifies whether simulation messages will be supressed or not. */ 00422 bool verbose_; 00423 00424 /** A map that stores the available QoS levels for this Scheduler. */ 00425 QOS_AVLTREE qos_avltree_; 00426 00427 /** Pointer to the current QoS-level. */ 00428 QoSLevel* qos_current_; 00429 00430 /** Pointer to the system. 00431 * Used by tasks to figure out their next branching points. 00432 */ 00433 DREAM::System* system_ptr_; 00434 }; 00435 00436 00437 /** Non-concurrent Scheduler model. 00438 * This implementation can be used to manage non-concurrent Nodes such as Channels the DRE Semantic Domain. 00439 */ 00440 class NonConcurrentScheduler : public DREAM::Scheduler 00441 { 00442 public: 00443 /** Constructor. */ 00444 NonConcurrentScheduler (const std::string& id, DREAM::System* system_ptr); 00445 00446 /** Destructor. */ 00447 virtual ~NonConcurrentScheduler (); 00448 00449 /** Schedules a Node for execution in a non-concurrent fashion. */ 00450 virtual void schedule (bool israndom = true) 00451 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00452 throw (DREAM::Exception) 00453 #endif 00454 ; 00455 }; 00456 00457 /** Fixed priority-based Scheduler model. 00458 * This class is the implementation of the static priority-based Scheduler in the DRE Semantic Domain. 00459 */ 00460 class FixedPriorityScheduler : public DREAM::Scheduler 00461 { 00462 public: 00463 /** Constructor. */ 00464 FixedPriorityScheduler (const std::string& id, DREAM::System* system_ptr, uint CPUs = 1); 00465 00466 /** Destructor. */ 00467 virtual ~FixedPriorityScheduler (); 00468 00469 /** Returns the number of CPUs managed by the FixedPriorityScheduler. */ 00470 virtual uint CPUs () const; 00471 00472 /** Returns true if the Task is deployed on the highest priority Thread. */ 00473 virtual bool highestpriority (const DREAM::Node* node_ptr) const 00474 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00475 throw (DREAM::Exception) 00476 #endif 00477 ; 00478 00479 /** Returns true if the Task is deployed on the lowest priority Thread. */ 00480 virtual bool lowestpriority (const DREAM::Node* node_ptr) const 00481 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00482 throw (DREAM::Exception) 00483 #endif 00484 ; 00485 00486 /** Returns true if the Scheduler is non-preemptive (has only 1 thread). */ 00487 virtual bool nonpreemptive () const 00488 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00489 throw (DREAM::Exception) 00490 #endif 00491 ; 00492 00493 /** Schedules a Node for execution. 00494 * This function will choose the highest subpriority Node in the highest priority frame and schedule it for execution 00495 * by calling Node::execute (). Multiple Tasks will be scheduled from multi-threaded Lanes on a multiprocessor platform. 00496 * @param deterministic specifies whether randomness is allowed. 00497 */ 00498 virtual void schedule (bool deterministic) 00499 throw (DREAM::Exception); 00500 00501 /** Starts deterministic simulation. 00502 * This simulation will simulate a deterministic trace of the system. 00503 */ 00504 virtual void simulate (bool verbose, bool deterministic = false) 00505 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING 00506 throw (DREAM::Exception) 00507 #endif 00508 ; 00509 }; 00510 00511 } 00512 00513 #endif 00514