00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include "Task.h"
00052
00053 namespace DREAM
00054 {
00055
00056
00057
00058
00059
00060
00061
00062 Node::Node (const std::string& id, DREAM::Thread* thread_ptr, bool executed = false)
00063 : id_ (id),
00064 thread_ptr_ (thread_ptr),
00065 executed_ (executed),
00066 clock_exec_ (0),
00067 remote_dep_ (false)
00068 {
00069 dependent_map_ = new DREAM::NodeList ();
00070 if (thread_ptr)
00071 thread_ptr->add (this);
00072 }
00073
00074 Node::Node (const DREAM::Node& node)
00075 : id_ (node.id_),
00076 thread_ptr_ (node.thread_ptr_),
00077 executed_ (node.executed_),
00078 clock_exec_ (node.clock_exec_),
00079 remote_dep_ (false)
00080 {
00081 dependent_map_ = new DREAM::NodeList ();
00082 if (node.thread_ptr_)
00083 node.thread_ptr_->add (this);
00084 }
00085
00086 Node::~Node ()
00087 {
00088 delete dependent_map_;
00089 }
00090
00091 inline void Node::add_dependent (DREAM::Node* node_ptr)
00092 {
00093 dependent_map_->add (node_ptr);
00094 }
00095
00096 uint Node::bcet () const
00097 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00098 throw (DREAM::Exception)
00099 #endif
00100 {
00101 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00102 std::string message;
00103 message << "Node \"" << id_ << "\" does not have best case execution time. Use the inherited classes which implement this feature.";
00104 throw DREAM::BaseClassException (message);
00105 #else
00106 return 0;
00107 #endif
00108 }
00109
00110 void Node::bcet (uint bcet)
00111 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00112 throw (DREAM::Exception)
00113 #endif
00114 {
00115 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00116 std::string message;
00117 message << "Node \"" << id_ << "\" does not have best case execution time. Use the inherited classes which implement this feature.";
00118 throw DREAM::BaseClassException (message);
00119 #endif
00120 }
00121
00122 #ifdef DREAM_BRANCHING
00123 void Node::branching_point ()
00124 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00125 throw (DREAM::Exception)
00126 #endif
00127 {
00128 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00129 std::string message;
00130 message << "Node \"" << id_ << "\" does not have branching points. Use the inherited classes which implement this feature.";
00131 throw DREAM::BaseClassException (message);
00132 #endif
00133 }
00134 #endif
00135
00136 DREAM::Context Node::context () const
00137 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00138 throw (DREAM::Exception)
00139 #endif
00140 {
00141 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00142 std::string message;
00143 message << "Node \"" << id_ << "\" does not have context. Use the inherited classes which implement this feature.";
00144 throw DREAM::BaseClassException (message);
00145 #else
00146 return DREAM::randomcase;
00147 #endif
00148 }
00149
00150 void Node::context (DREAM::Context context)
00151 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00152 throw (DREAM::Exception)
00153 #endif
00154 {
00155 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00156 std::string message;
00157 message << "Node \"" << id_ << "\" does not have context. Use the inherited classes which implement this feature.";
00158 throw DREAM::BaseClassException (message);
00159 #endif
00160 }
00161
00162 double Node::clock_dl () const
00163 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00164 throw (DREAM::Exception)
00165 #endif
00166 {
00167 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00168 std::string message;
00169 message << "Node \"" << id_ << "\" does not have deadline clock. Use the inherited classes which implement this feature.";
00170 throw DREAM::BaseClassException (message);
00171 #else
00172 return 0;
00173 #endif
00174 }
00175
00176 double Node::clock_dl_reset () const
00177 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00178 throw (DREAM::Exception)
00179 #endif
00180 {
00181 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00182 std::string message;
00183 message << "Node \"" << id_ << "\" does not have deadline clock. Use the inherited classes which implement this feature.";
00184 throw DREAM::BaseClassException (message);
00185 #else
00186 return 0;
00187 #endif
00188 }
00189
00190 inline double Node::clock_exec () const
00191 {
00192 return clock_exec_;
00193 }
00194
00195 inline void Node::clock_exec_reset ()
00196 {
00197 clock_exec_ = 0;
00198 }
00199
00200 inline void Node::clock_step (double clock_step)
00201 {
00202 clock_exec_ += clock_step;
00203 }
00204
00205 void Node::consume ()
00206 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00207 throw (DREAM::Exception)
00208 #endif
00209 {
00210 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00211 std::string message;
00212 message << "Node \"" << id_ << "\" does not consume events. Use the inherited classes which implement this feature.";
00213 throw DREAM::BaseClassException (message);
00214 #endif
00215 }
00216
00217 uint Node::deadline () const
00218 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00219 throw (DREAM::Exception)
00220 #endif
00221 {
00222 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00223 std::string message;
00224 message << "Node \"" << id_ << "\" does not have deadline. Use the inherited classes which implement this feature.";
00225 throw DREAM::BaseClassException (message);
00226 #else
00227 return 0;
00228 #endif
00229 }
00230
00231 void Node::deadline (uint deadline)
00232 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00233 throw (DREAM::Exception)
00234 #endif
00235 {
00236 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00237 std::string message;
00238 message << "Node\"" << id_ << "\" does not have deadline. Use the inherited classes which implement this feature.";
00239 throw DREAM::BaseClassException (message);
00240 #endif
00241 }
00242
00243 void Node::deploy (DREAM::Thread* thread_ptr)
00244 {
00245 if (thread_ptr_)
00246 thread_ptr_->erase (id_);
00247
00248 thread_ptr_ = thread_ptr;
00249 thread_ptr->add (this);
00250 }
00251
00252 inline bool Node::executed () const
00253 {
00254 return executed_;
00255 }
00256
00257 inline void Node::executed (bool executed)
00258 {
00259 executed_ = executed;
00260 }
00261
00262 inline Node* Node::get_dependent (const std::string& id) const
00263 {
00264 return dependent_map_->find (id);
00265 }
00266
00267 inline const NODE_MAP* Node::get_dependent_map () const
00268 {
00269 return dependent_map_->get_map ();
00270 }
00271
00272 const DREAM::Node* Node::get_source (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map) const
00273 throw (DREAM::Exception)
00274 {
00275 DREAM::Node* node_ptr = NULL;
00276
00277
00278 for (DREAM::NODE_MAP::const_iterator node_iter = channel_map->begin (); node_iter != channel_map->end (); node_iter++)
00279 {
00280 if (node_iter->second->get_dependent (id_))
00281 return NULL;
00282 };
00283
00284
00285 for (DREAM::NODE_MAP::const_iterator node_iter = task_map->begin (); node_iter != task_map->end (); node_iter++)
00286 {
00287 if (node_iter->second->get_dependent (id_))
00288 {
00289 if (!node_ptr)
00290 node_ptr = node_iter->second;
00291 else
00292 throw DREAM::Exception ("Node::get_source () found multiple non-channel sources.");
00293 }
00294 };
00295
00296
00297 for (DREAM::NODE_MAP::const_iterator node_iter = timer_map->begin (); node_iter != timer_map->end (); node_iter++)
00298 {
00299 if (node_iter->second->get_dependent (id_))
00300 {
00301 if (!node_ptr)
00302 node_ptr = node_iter->second;
00303 else
00304 throw DREAM::Exception ("Node::get_source () found multiple non-channel sources.");
00305 }
00306 };
00307
00308 if (!node_ptr)
00309 throw DREAM::Exception ("Node::get_source () construction failed. Most likely the input models are semantically incorrect.");
00310
00311 return node_ptr;
00312 }
00313
00314 inline std::string Node::id () const
00315 {
00316 return id_;
00317 }
00318
00319 bool Node::isidle () const
00320 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00321 throw (DREAM::Exception)
00322 #endif
00323 {
00324 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00325 std::string message;
00326 message << "Node\"" << id_ << "\" cannot be checked for idleness. Use the inherited classes which implement this feature.";
00327 throw DREAM::BaseClassException (message);
00328 #else
00329 return false;
00330 #endif
00331 }
00332
00333 inline double Node::next_event ()
00334 {
00335 return 0.0;
00336 }
00337
00338 #ifdef DREAM_BRANCHING
00339 void Node::next_et (double next_et)
00340 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00341 throw (DREAM::Exception)
00342 #endif
00343 {
00344 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00345 std::string message;
00346 message << "Node\"" << id_ << "\" does not have clocks. Use the inherited classes which implement this feature.";
00347 throw DREAM::BaseClassException (message);
00348 #endif
00349 }
00350 #endif
00351
00352 void Node::preempt ()
00353 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00354 throw (DREAM::Exception)
00355 #endif
00356 {
00357 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00358 std::string message;
00359 message << "Node\"" << id_ << "\" cannot be preempted. Use the inherited classes which implement this feature.";
00360 throw DREAM::BaseClassException (message);
00361 #endif
00362 }
00363
00364 uint Node::priority () const
00365 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00366 throw (DREAM::Exception)
00367 #endif
00368 {
00369 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00370 std::string message;
00371 message << "Node\"" << id_ << "\" does not have priority. Use the inherited classes which implement this feature.";
00372 throw DREAM::BaseClassException (message);
00373 #else
00374 return 0;
00375 #endif
00376 }
00377
00378 void Node::priority (uint priority)
00379 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00380 throw (DREAM::Exception)
00381 #endif
00382 {
00383 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00384 std::string message;
00385 message << "Node\"" << id_ << "\" does not have priority. Use the inherited classes which implement this feature.";
00386 throw DREAM::BaseClassException (message);
00387 #endif
00388 }
00389
00390 inline void Node::publish ()
00391 {
00392 if (thread_ptr_)
00393 {
00394 #ifdef DREAM_VERBOSE2
00395 if (Option::verbose1_ && Option::verbose2_)
00396 {
00397 std::string message;
00398 thread_ptr_->trace (message << id_ << " is publishing...");
00399 }
00400 #endif
00401 dependent_map_->publish ();
00402 thread_ptr_->scheduler ()->system ()->relevant_event (true);
00403 }
00404 }
00405
00406 inline void Node::remove_dependent (const std::string& id)
00407 {
00408 dependent_map_->erase (id);
00409 }
00410
00411 inline bool Node::remote_dep () const
00412 {
00413 return remote_dep_;
00414 }
00415
00416 inline void Node::remote_dep (bool flag)
00417 {
00418 remote_dep_ = flag;
00419 }
00420
00421 inline void Node::reset ()
00422 {
00423 clock_exec_reset ();
00424
00425 }
00426
00427 inline DREAM::Scheduler* Node::scheduler () const
00428 {
00429 return thread_ptr_? thread_ptr_->scheduler () : NULL;
00430 }
00431
00432 uint Node::subpriority () const
00433 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00434 throw (DREAM::Exception)
00435 #endif
00436 {
00437 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00438 std::string message;
00439 message << "Node\"" << id_ << "\" does not have subpriority. Use the inherited classes which implement this feature.";
00440 throw DREAM::BaseClassException (message);
00441 #else
00442 return 0;
00443 #endif
00444 }
00445
00446 void Node::subpriority (uint subpriority)
00447 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00448 throw (DREAM::Exception)
00449 #endif
00450 {
00451 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00452 std::string message;
00453 message << "Node\"" << id_ << "\" does not have subpriority. Use the inherited classes which implement this feature.";
00454 throw DREAM::BaseClassException (message);
00455 #endif
00456 }
00457
00458 void Node::take_transitions ()
00459 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00460 throw (DREAM::Exception)
00461 #endif
00462 {
00463 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00464 std::string message;
00465 message << "Node\"" << id_ << "\" does not take transitions. Use the inherited classes which implement this feature.";
00466 throw DREAM::BaseClassException (message);
00467 #endif
00468 }
00469
00470 uint Node::wcet () const
00471 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00472 throw (DREAM::Exception)
00473 #endif
00474 {
00475 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00476 std::string message;
00477 message << "Node\"" << id_ << "\" does not have worst case execution time. Use the inherited classes which implement this feature.";
00478 throw DREAM::BaseClassException (message);
00479 #else
00480 return 0;
00481 #endif
00482 }
00483
00484 void Node::wcet (uint wcet)
00485 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00486 throw (DREAM::Exception)
00487 #endif
00488 {
00489 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00490 std::string message;
00491 message << "Node\"" << id_ << "\" does not have worst case execution time. Use the inherited classes which implement this feature.";
00492 throw DREAM::BaseClassException (message);
00493 #endif
00494 }
00495
00496
00497
00498
00499
00500
00501
00502 Timer::Timer (const std::string& id, DREAM::Thread* thread_ptr, uint period)
00503 : DREAM::Node (id, thread_ptr, true),
00504 period_ (period),
00505 bcperiod_ (period),
00506 context_ (randomcase),
00507 et_ (period)
00508 #ifdef DREAM_BRANCHING
00509 ,next_et_ (0.0)
00510 #endif
00511 {
00512 if (period == 0)
00513 throw DREAM::Exception ("Timer period has to be greater than 0.");
00514 }
00515
00516 Timer::Timer (const std::string& id, DREAM::Thread* thread_ptr, uint period, uint bcperiod)
00517 : DREAM::Node (id, thread_ptr, true),
00518 period_ (period),
00519 bcperiod_ (bcperiod),
00520 context_ (randomcase),
00521 et_ (bcperiod + random (period - bcperiod))
00522 #ifdef DREAM_BRANCHING
00523 ,next_et_ (0.0)
00524 #endif
00525 {
00526 if ((period == 0) || (bcperiod == 0))
00527 throw DREAM::Exception ("Timer period has to be greater than 0.");
00528 if (period <= bcperiod)
00529 throw DREAM::Exception ("Timer best case period has to be smaller than the period.");
00530 }
00531
00532 Timer::Timer (const DREAM::Timer& timer)
00533 : DREAM::Node (timer.id_, timer.thread_ptr_, true),
00534 period_ (timer.period_),
00535 bcperiod_ (timer.bcperiod_),
00536 context_ (timer.context_),
00537 et_ (timer.et_)
00538 #ifdef DREAM_BRANCHING
00539 ,next_et_ (timer.bcperiod_)
00540 #endif
00541 {
00542 if ((timer.period_ == 0) || (timer.bcperiod_ == 0))
00543 throw DREAM::Exception ("Timer period has to be greater than 0.");
00544 }
00545
00546
00547 Timer::~Timer ()
00548 {
00549 }
00550
00551 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00552 uint Timer::bcet () const
00553 throw (DREAM::Exception)
00554 #else
00555 inline uint Timer::bcet () const
00556 #endif
00557 {
00558 return bcperiod_;
00559 }
00560
00561 #ifdef DREAM_BRANCHING
00562 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00563 void Timer::branching_point ()
00564 throw (DREAM::Exception)
00565 #else
00566 inline void Timer::branching_point ()
00567 #endif
00568 {
00569 if (context_ == branchingpoint)
00570 if (et_ == next_et_)
00571 {
00572 context_ = bestcase;
00573 et_ = bcperiod_;
00574 next_et_ = 0.0;
00575 }
00576 else
00577 {
00578 et_ = next_et_;
00579 }
00580 }
00581 #endif
00582
00583 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00584 DREAM::Context Timer::context () const
00585 throw (DREAM::Exception)
00586 #else
00587 inline DREAM::Context Timer::context () const
00588 #endif
00589 {
00590 return context_;
00591 }
00592
00593 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00594 void Timer::context (DREAM::Context context)
00595 throw (DREAM::Exception)
00596 #else
00597 inline void Timer::context (DREAM::Context context)
00598 #endif
00599 {
00600 context_ = context;
00601 }
00602
00603 inline void Timer::clock_exec_reset ()
00604 {
00605 clock_exec_ = 0;
00606
00607
00608 if (context_ == worstcase)
00609 et_ = period_;
00610 else if (context_ == randomcase)
00611 et_ = bcperiod_ + random (period_ - bcperiod_);
00612 else if (context_ == bestcase)
00613 et_ = bcperiod_;
00614 }
00615
00616 void Timer::clock_step (double clock_step)
00617 {
00618
00619 clock_exec_ += clock_step;
00620
00621 #ifdef DREAM_BRANCHING
00622
00623 if (bcperiod_ < clock_exec_)
00624 {
00625 if (next_et_ < clock_exec_)
00626 {
00627 if ((clock_exec_ < period_) && remote_dep_ && Option::branching_)
00628 {
00629
00630
00631 if (thread_ptr_->scheduler ()->system ()->relevant_event ())
00632 {
00633
00634 std::string message;
00635 thread_ptr_->trace (message << "Branching point " << id_ << " bcperiod: " << bcperiod_ << " period: " << period_ << " next_et: " << clock_exec_);
00636
00637 if (context_ == worstcase)
00638 context_ = branchingpoint;
00639
00640 next_et_ = clock_exec_;
00641 }
00642 }
00643 }
00644 }
00645 #endif
00646 }
00647
00648 inline double Timer::next_event ()
00649 {
00650 return (et_ - clock_exec_);
00651 }
00652
00653 #ifdef DREAM_BRANCHING
00654 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00655 void Timer::next_et (double next_et)
00656 throw (DREAM::Exception)
00657 #else
00658 inline void Timer::next_et (double next_et)
00659 #endif
00660 {
00661 next_et_ = next_et;
00662 }
00663 #endif
00664
00665 uint Timer::priority () const
00666 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00667 throw (DREAM::Exception)
00668 #endif
00669 {
00670 uint priority = maxuint;
00671
00672 NODE_MAP* node_map = dependent_map_->get_map ();
00673
00674 for (DREAM::NODE_MAP::const_iterator node_iter = node_map->begin (); node_iter != node_map->end (); node_iter++)
00675 {
00676 if (priority == maxuint) priority = node_iter->second->priority ();
00677 else
00678 {
00679 if (priority > node_iter->second->priority ())
00680 priority = node_iter->second->priority ();
00681 }
00682 }
00683
00684 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00685 if (priority == maxuint)
00686 {
00687 std::string message;
00688 message << "Timer \"" << id_ << "\" has no dependents";
00689 throw DREAM::Exception (message);
00690 }
00691 #endif
00692
00693 return priority;
00694 }
00695
00696 inline void Timer::publish ()
00697 {
00698 if (thread_ptr_)
00699 {
00700 #ifdef DREAM_VERBOSE2
00701 if (Option::verbose1_ && Option::verbose2_)
00702 {
00703 std::string message;
00704 message << id_ << " is publishing...";
00705 thread_ptr_->trace (message);
00706 }
00707 #endif
00708 dependent_map_->publish ();
00709 thread_ptr_->scheduler ()->system ()->relevant_event (true);
00710 }
00711 }
00712
00713 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00714 void Timer::take_transitions ()
00715 throw (DREAM::Exception)
00716 #else
00717 inline void Timer::take_transitions ()
00718 #endif
00719 {
00720 #ifdef DREAM_VERBOSE2
00721
00722
00723
00724
00725
00726 #endif
00727
00728
00729 if (clock_exec_ == et_)
00730 {
00731 publish ();
00732 clock_exec_reset ();
00733 }
00734
00735 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00736 if (clock_exec_ > et_)
00737 {
00738 std::string message;
00739 message << "Execution clock value in Timer \"" << id_ << "\" is greater than the period. Most likely the period was set during simulation time. Please report bug at http://sourceforge.net/projects/dre!";
00740 throw DREAM::Exception (message);
00741 }
00742 #endif
00743 }
00744
00745 void Timer::visitor_if (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map, std::ofstream& f_stream)
00746 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00747 throw (DREAM::Exception)
00748 #endif
00749 {
00750 f_stream << "/*\n * Timer - " << id_ << "\n *\n */\n" << std::endl;
00751
00752 f_stream << "process timer_" << id_ << " (1);\n\n"
00753 << "var ce clock;\nconst period_" << id_ << "=" << period_ << ";\n\n"
00754 << "state start #start ;\n"
00755 << "\tdeadline eager;\n"
00756 << "\tset ce := 0;\n"
00757 << "\tnextstate timer;\n"
00758 << "endstate;\n\n"
00759 << "state timer;\n"
00760 << "\tdeadline eager;\n"
00761 << "\twhen ce = period_" << id_ << ";\n";
00762
00763 const DREAM::NODE_MAP* node_map = get_dependent_map ();
00764 const DREAM::NODE_MAP* node_map2;
00765
00766
00767 DREAM::NODE_MAP::const_iterator task_iter, task_iter2, find_iter;
00768
00769 for (task_iter = node_map->begin (); task_iter != node_map->end (); task_iter++)
00770 {
00771 find_iter = task_map->find (task_iter->first);
00772 if (find_iter != task_map->end ())
00773 f_stream << "\toutput event () to {task_" << find_iter->first << "}0;\n";
00774 else
00775 {
00776 find_iter = channel_map->find (task_iter->first);
00777
00778
00779 if (find_iter->second)
00780 node_map2 = find_iter->second->get_dependent_map ();
00781
00782 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00783 else
00784 {
00785 std::string message;
00786 message << "Channel " << task_iter->first << " has no Task dependents. Incorrect model.";
00787 throw DREAM::Exception (message);
00788 }
00789 #endif
00790
00791 for (task_iter2 = node_map2->begin (); task_iter2 != node_map2->end (); task_iter2++)
00792 {
00793 find_iter = node_map2->find (task_iter2->first);
00794 if (find_iter != node_map2->end ())
00795 {
00796 if (task_iter->second->wcet () != 0)
00797 f_stream << "\toutput event () via {" << task_iter->first << "}0 to {task_" << find_iter->first << "}0;\n";
00798 else
00799 f_stream << "\toutput event () /* via {" << task_iter->first << "}0 */ to {task_" << find_iter->first << "}0;\n";
00800 }
00801
00802 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00803 else
00804 {
00805 std::string message;
00806 message << "Node " << task_iter2->first << " could not be found as a Channel dependent in the Task list when generating IF input. Incorrect model.";
00807 throw DREAM::Exception (message);
00808 }
00809 #endif
00810
00811 }
00812 }
00813 }
00814
00815 f_stream << "\tset ce := 0;\n"
00816 << "\t\tnextstate timer;\n"
00817 << "endstate;\n\nendprocess;\n" << std::endl;
00818
00819 }
00820
00821 void Timer::visitor_map (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map)
00822 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00823 throw (DREAM::Exception)
00824 #endif
00825 {
00826 timer_map->insert (DREAM::NODE_PAIR (id_, this));
00827 }
00828
00829 void Timer::visitor_uppaal (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map, std::ofstream& f_stream)
00830 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00831 throw (DREAM::Exception)
00832 #endif
00833 {
00834 f_stream << id_ << " := Timer (" << period_ << ", " << bcperiod_ << ", " << "publish" << id_ << ");" << std::endl;
00835 }
00836
00837 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00838 uint Timer::wcet () const
00839 throw (DREAM::Exception)
00840 #else
00841 inline uint Timer::wcet () const
00842 #endif
00843 {
00844 return period_;
00845 }
00846
00847
00848
00849
00850
00851
00852
00853 Channel::Channel (const std::string& id, DREAM::Thread* thread_ptr, uint delay, uint buffersize)
00854 : DREAM::Node (id, thread_ptr, true),
00855 state_ (idle),
00856 delay_ (delay),
00857 bcdelay_ (delay),
00858 buffersize_ (buffersize),
00859 context_ (randomcase),
00860 et_ (delay),
00861 #ifdef DREAM_BRANCHING
00862 next_et_ (0.0),
00863 #endif
00864 buffer_ (0)
00865 {
00866 }
00867
00868 Channel::Channel (const std::string& id, DREAM::Thread* thread_ptr, uint delay, uint bcdelay, uint buffersize)
00869 : DREAM::Node (id, thread_ptr, true),
00870 state_ (idle),
00871 delay_ (delay),
00872 bcdelay_ (bcdelay),
00873 buffersize_ (buffersize),
00874 context_ (randomcase),
00875 et_ (bcdelay + random (delay - bcdelay)),
00876 #ifdef DREAM_BRANCHING
00877 next_et_ (0.0),
00878 #endif
00879 buffer_ (0)
00880 {
00881 if (delay <= bcdelay)
00882 throw DREAM::Exception ("Channel best case delay has to be smaller than the delay.");
00883 }
00884
00885 Channel::Channel (const DREAM::Channel& channel)
00886 : DREAM::Node (channel.id_, channel.thread_ptr_, true),
00887 state_ (channel.state_),
00888 delay_ (channel.delay_),
00889 bcdelay_ (channel.bcdelay_),
00890 buffersize_ (channel.buffersize_),
00891 context_ (channel.context_),
00892 et_ (channel.et_),
00893 #ifdef DREAM_BRANCHING
00894 next_et_ (channel.bcdelay_),
00895 #endif
00896 buffer_ (channel.buffer_)
00897 {
00898 }
00899
00900 Channel::~Channel ()
00901 {
00902 }
00903
00904 void Channel::add_dependent (DREAM::Node* node_ptr)
00905 throw (DREAM::Exception)
00906 {
00907 if (dependent_map_->get_map ()->size () > 0)
00908 throw DREAM::Exception ("Channel::add_dependent (): Channels cannot have more than 1 dependents.");
00909
00910 dependent_map_->add (node_ptr);
00911 }
00912
00913 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00914 uint Channel::bcet () const
00915 throw (DREAM::Exception)
00916 #else
00917 inline uint Channel::bcet () const
00918 #endif
00919 {
00920 return bcdelay_;
00921 }
00922
00923 #ifdef DREAM_BRANCHING
00924 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00925 void Channel::branching_point ()
00926 throw (DREAM::Exception)
00927 #else
00928 inline void Channel::branching_point ()
00929 #endif
00930 {
00931 if (context_ == branchingpoint)
00932 if (et_ == next_et_)
00933 {
00934 context_ = bestcase;
00935 et_ = bcdelay_;
00936 next_et_ = 0.0;
00937 }
00938 else
00939 {
00940 et_ = next_et_;
00941 }
00942 }
00943 #endif
00944
00945 inline void Channel::clock_exec_reset ()
00946 {
00947 clock_exec_ = 0;
00948
00949
00950 if (context_ == worstcase)
00951 et_ = delay_;
00952 else if (context_ == randomcase)
00953 et_ = bcdelay_ + random (delay_ - bcdelay_);
00954 else if (context_ == bestcase)
00955 et_ = bcdelay_;
00956 }
00957
00958 inline void Channel::clock_step (double clock_step)
00959 {
00960
00961 if (buffer_ != 0) clock_exec_ += clock_step;
00962
00963 #ifdef DREAM_BRANCHING
00964
00965 if (bcdelay_ < clock_exec_)
00966 {
00967 if ((clock_exec_ < delay_) && remote_dep_ && Option::branching_)
00968 {
00969 if (next_et_ < clock_exec_)
00970 {
00971
00972
00973 if (thread_ptr_->scheduler ()->system ()->relevant_event ())
00974 {
00975
00976 std::string message;
00977 thread_ptr_->trace (message << "Branching point " << id_ << " bcdelay: " << bcdelay_ << " wcdelay: " << delay_ << " next_et: " << clock_exec_);
00978 if (context_ == worstcase)
00979 context_ = branchingpoint;
00980
00981 next_et_ = clock_exec_;
00982 }
00983 }
00984 }
00985 }
00986 #endif
00987 }
00988
00989 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00990 void Channel::consume ()
00991 throw (DREAM::Exception)
00992 #else
00993 inline void Channel::consume ()
00994 #endif
00995 {
00996 if ((buffer_ < buffersize_) || (buffersize_ == 0))
00997 {
00998 thread_ptr_->enqueue (this);
00999
01000 ++buffer_;
01001
01002 if (state_ == idle)
01003 {
01004 state_ = wait;
01005 clock_exec_reset ();
01006 }
01007
01008 take_transitions ();
01009 }
01010 }
01011
01012 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01013 DREAM::Context Channel::context () const
01014 throw (DREAM::Exception)
01015 #else
01016 inline DREAM::Context Channel::context () const
01017 #endif
01018 {
01019 return context_;
01020 }
01021
01022 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01023 void Channel::context (DREAM::Context context)
01024 throw (DREAM::Exception)
01025 #else
01026 inline void Channel::context (DREAM::Context context)
01027 #endif
01028 {
01029 context_ = context;
01030 }
01031
01032 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01033 bool Channel::idle_dependents () const
01034 throw (DREAM::Exception)
01035 #else
01036 inline bool Channel::idle_dependents () const
01037 #endif
01038 {
01039 for (DREAM::NODE_MAP::const_iterator dependent_iter = dependent_map_->get_map ()->begin ();
01040 dependent_iter != dependent_map_->get_map ()->end ();
01041 dependent_iter++)
01042 if (! dependent_iter->second->isidle ())
01043 return false;
01044
01045 return true;
01046 }
01047
01048 inline double Channel::next_event ()
01049 {
01050
01051
01052 return (buffer_ && state_ == wait) ? (et_ - clock_exec_) : 0.0;
01053 }
01054
01055 #ifdef DREAM_BRANCHING
01056 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01057 void Channel::next_et (double next_et)
01058 throw (DREAM::Exception)
01059 #else
01060 inline void Channel::next_et (double next_et)
01061 #endif
01062 {
01063 next_et_ = next_et;
01064 }
01065 #endif
01066
01067 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01068 void Channel::publish ()
01069 throw (DREAM::Exception)
01070 #else
01071 inline void Channel::publish ()
01072 #endif
01073 {
01074 #ifdef DREAM_VERBOSE2
01075 if (Option::verbose1_ && Option::verbose2_)
01076 {
01077 std::string message;
01078 message << id_ << " is publishing...";
01079 thread_ptr_->trace (message);
01080 }
01081 #endif
01082
01083 dependent_map_->publish ();
01084 thread_ptr_->scheduler ()->system ()->relevant_event (true);
01085 }
01086
01087 inline void Channel::reset ()
01088 {
01089 buffer_ = 0;
01090 state_ = idle;
01091 clock_exec_reset ();
01092 }
01093
01094 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01095 void Channel::take_transitions ()
01096 throw (DREAM::Exception)
01097 #else
01098 inline void Channel::take_transitions ()
01099 #endif
01100 {
01101 #ifdef DREAM_VERBOSE2
01102
01103
01104
01105
01106
01107 #endif
01108
01109 switch (state_)
01110 {
01111 case idle:
01112
01113 if (0 < buffer_)
01114 if (idle_dependents ())
01115 {
01116 state_ = wait;
01117 clock_exec_reset ();
01118 take_transitions ();
01119 }
01120 break;
01121 case wait:
01122
01123 if (clock_exec_ == et_)
01124 {
01125 if (idle_dependents ())
01126 {
01127 state_ = idle;
01128 if (--buffer_ == 0)
01129 thread_ptr_->dequeue (this);
01130 publish ();
01131 }
01132 else
01133 state_ = idle;
01134 }
01135 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01136 else if (clock_exec_ > et_)
01137 {
01138 std::string message;
01139 message << "Execution time in Channel \"" << id_ << "\" is greater than the delay. Please report bug at http://sourceforge.net/projects/dre!";
01140 throw DREAM::Exception (message);
01141 }
01142 #endif
01143 }
01144 }
01145
01146 void Channel::visitor_map (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map)
01147 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01148 throw (DREAM::Exception)
01149 #endif
01150 {
01151 channel_map->insert (DREAM::NODE_PAIR (id_, this));
01152 }
01153
01154 void Channel::visitor_uppaal (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map, std::ofstream& f_stream)
01155 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01156 throw (DREAM::Exception)
01157 #endif
01158 {
01159 if (delay_ == 0)
01160 f_stream << id_ << " := Buffer (" << buffersize_ << ", ";
01161 else
01162 f_stream << id_ << " := Channel (" << delay_ << ", " << bcdelay_ << ", " << buffersize_ << ", ";
01163
01164 DREAM::NODE_MAP* dependent_map = dependent_map_->get_map ();
01165
01166 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01167 if (dependent_map->size () > 1)
01168 throw DREAM::Exception ("Channel::visitor_uppaal () called for a Channel with multiple dependents, This is an invalid modeling construct for the Uppaal models. Please use multiple channels with only ONE dependent each!");
01169 #endif
01170
01171 DREAM::NODE_MAP::const_iterator dependent_iter, task_iter;
01172 dependent_iter = dependent_map->begin ();
01173
01174 uint i = 0;
01175
01176
01177 for (task_iter = task_map->begin (); task_iter != task_map->end (); task_iter++)
01178 {
01179 if (task_iter->first == dependent_iter->first) break;
01180 ++i;
01181 }
01182
01183 std::string dependent = task_iter->first;
01184
01185 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01186 if (task_iter == task_map->end ())
01187 throw DREAM::Exception ("Channel::visitor_uppaal () called for a Channel with a non-task dependent. Invalid modeling construct. Please report bug at http://sourceforge.net/projects/dre!");
01188 #endif
01189
01190 f_stream << i << ", ";
01191
01192 if (get_source (task_map, channel_map, timer_map))
01193 {
01194 f_stream << "publish" << get_source (task_map, channel_map, timer_map)->id ()
01195 << ", start" << dependent
01196 << ", publish" << dependent << ");" << std::endl;
01197 }
01198 else
01199 {
01200 f_stream << ", start" << dependent
01201 << ", publish" << dependent << ");" << std::endl;
01202 }
01203 }
01204
01205 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01206 uint Channel::wcet () const
01207 throw (DREAM::Exception)
01208 #else
01209 inline uint Channel::wcet () const
01210 #endif
01211 {
01212 return delay_;
01213 }
01214
01215
01216
01217
01218
01219
01220
01221 Task::Task (const std::string& id, DREAM::Thread* thread_ptr, uint wcet, uint deadline)
01222 : DREAM::Node (id, thread_ptr),
01223 wcet_ (wcet),
01224 bcet_ (wcet),
01225 context_ (randomcase),
01226 et_ (wcet),
01227 deadline_ (deadline),
01228 state_ (idle),
01229 clock_dl_ (0.0)
01230 #ifdef DREAM_BRANCHING
01231 ,next_et_ (0.0)
01232 #endif
01233 #ifndef DREAM_RACE_CONDITION_ZERO
01234 ,zero_delay_race_condition_ (2)
01235 #endif
01236 {
01237 }
01238
01239 Task::Task (const std::string& id, DREAM::Thread* thread_ptr, uint wcet, uint deadline, uint subpriority)
01240 : DREAM::Node (id, thread_ptr),
01241 wcet_ (wcet),
01242 bcet_ (wcet),
01243 context_ (randomcase),
01244 et_ (wcet),
01245 deadline_ (deadline),
01246 subpriority_ (subpriority),
01247 state_ (idle),
01248 clock_dl_ (0.0)
01249 #ifdef DREAM_BRANCHING
01250 ,next_et_ (0.0)
01251 #endif
01252 #ifndef DREAM_RACE_CONDITION_ZERO
01253 ,zero_delay_race_condition_ (2)
01254 #endif
01255 {
01256 }
01257
01258 Task::Task (const std::string& id, DREAM::Thread* thread_ptr, uint wcet, uint bcet, uint deadline, uint subpriority)
01259 : DREAM::Node (id, thread_ptr),
01260 wcet_ (wcet),
01261 bcet_ (bcet),
01262 context_ (randomcase),
01263 et_ (bcet + random (wcet - bcet)),
01264 deadline_ (deadline),
01265 subpriority_ (subpriority),
01266 state_ (idle),
01267 clock_dl_ (0.0)
01268 #ifdef DREAM_BRANCHING
01269 ,next_et_ (0.0)
01270 #endif
01271 #ifndef DREAM_RACE_CONDITION_ZERO
01272 ,zero_delay_race_condition_ (2)
01273 #endif
01274 {
01275 if (wcet <= bcet)
01276 throw DREAM::Exception ("Task best case execution time has to be smaller than the worst case execution time.");
01277 }
01278
01279
01280 Task::Task (const std::string& id, DREAM::Thread* thread_ptr, uint wcet, uint bcet, uint deadline, uint subpriority,
01281 DREAM::Context context, double et, DREAM::State state, double clock_dl)
01282 : DREAM::Node (id, thread_ptr),
01283 wcet_ (wcet),
01284 bcet_ (bcet),
01285 context_ (context),
01286 et_ (et),
01287 deadline_ (deadline),
01288 subpriority_ (subpriority),
01289 state_ (state),
01290 clock_dl_ (clock_dl)
01291 #ifdef DREAM_BRANCHING
01292 ,next_et_ (0.0)
01293 #endif
01294 #ifndef DREAM_RACE_CONDITION_ZERO
01295 ,zero_delay_race_condition_ (2)
01296 #endif
01297 {
01298 if (wcet <= bcet)
01299 throw DREAM::Exception ("Task best case execution time has to be smaller than the worst case execution time.");
01300 }
01301
01302 Task::Task (const DREAM::Task& task)
01303 : DREAM::Node (task.id_, task.thread_ptr_),
01304 wcet_ (task.wcet_),
01305 bcet_ (task.bcet_),
01306 context_ (task.context_),
01307 et_ (task.et_),
01308 deadline_ (task.deadline_),
01309 subpriority_ (task.subpriority_),
01310 state_ (task.state_),
01311 clock_dl_ (task.clock_dl_)
01312 #ifdef DREAM_BRANCHING
01313 ,next_et_ (task.next_et_)
01314 #endif
01315 #ifndef DREAM_RACE_CONDITION_ZERO
01316 ,zero_delay_race_condition_ (task.zero_delay_race_condition_)
01317 #endif
01318 {
01319 }
01320
01321 Task::~Task ()
01322 {
01323 }
01324
01325 void Task::operator= (const DREAM::Task& task)
01326 {
01327 id_ = task.id_;
01328
01329
01330 wcet_ = task.wcet_;
01331 bcet_ = task.bcet_;
01332 context_ = task.context_;
01333 deadline_ = task.deadline_;
01334 subpriority_ = task.subpriority_;
01335 state_ = task.state_;
01336 clock_dl_ = task.clock_dl_;
01337 #ifdef DREAM_BRANCHING
01338 next_et_ = task.next_et_;
01339 #endif
01340 }
01341
01342 bool Task::operator== (const DREAM::Task& task)
01343 {
01344 if (id_ == task.id_)
01345
01346
01347
01348
01349
01350
01351
01352
01353 return true;
01354 else
01355 return false;
01356 }
01357
01358 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01359 uint Task::bcet () const
01360 throw (DREAM::Exception)
01361 #else
01362 inline uint Task::bcet () const
01363 #endif
01364 {
01365 return bcet_;
01366 }
01367
01368 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01369 void Task::bcet (uint bcet)
01370 throw (DREAM::Exception)
01371 #else
01372 inline void Task::bcet (uint bcet)
01373 #endif
01374 {
01375 bcet_ = bcet;
01376 }
01377
01378 #ifdef DREAM_BRANCHING
01379 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01380 void Task::branching_point ()
01381 throw (DREAM::Exception)
01382 #else
01383 inline void Task::branching_point ()
01384 #endif
01385 {
01386 if (context_ == branchingpoint)
01387 if (et_ == next_et_)
01388 {
01389 context_ = bestcase;
01390 et_ = bcet_;
01391 next_et_ = 0.0;
01392 }
01393 else
01394 {
01395 et_ = next_et_;
01396 }
01397 }
01398 #endif
01399
01400 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01401 DREAM::Context Task::context () const
01402 throw (DREAM::Exception)
01403 #else
01404 inline DREAM::Context Task::context () const
01405 #endif
01406 {
01407 return context_;
01408 }
01409
01410 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01411 void Task::context (DREAM::Context context)
01412 throw (DREAM::Exception)
01413 #else
01414 inline void Task::context (DREAM::Context context)
01415 #endif
01416 {
01417 context_ = context;
01418 }
01419
01420 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01421 double Task::clock_dl () const
01422 throw (DREAM::Exception)
01423 #else
01424 inline double Task::clock_dl () const
01425 #endif
01426 {
01427 return clock_dl_;
01428 }
01429
01430 inline void Task::clock_dl_reset ()
01431 {
01432 clock_dl_ = 0;
01433 }
01434
01435 inline void Task::clock_exec_reset ()
01436 {
01437 clock_exec_ = 0;
01438
01439
01440 if (context_ == worstcase)
01441 et_ = wcet_;
01442 else if (context_ == randomcase)
01443 et_ = bcet_ + random (wcet_ - bcet_);
01444 else if (context_ == bestcase)
01445 et_ = bcet_;
01446 }
01447
01448 inline void Task::clock_step (double clock_step)
01449 {
01450 if ((state_ == enabled) || (state_ == executing) || (state_ == preempted))
01451 clock_dl_ += clock_step;
01452 if (state_ == executing)
01453 clock_exec_ += clock_step;
01454
01455 #ifdef DREAM_BRANCHING
01456
01457 if (bcet_ < clock_exec_)
01458 {
01459 if ((clock_exec_ < wcet_) && remote_dep_ && Option::branching_)
01460 {
01461 if (clock_exec_ < et_)
01462 {
01463
01464
01465 if (thread_ptr_->scheduler ()->system ()->relevant_event ())
01466 {
01467
01468 std::string message;
01469 thread_ptr_->trace (message << "Branching point " << id_ << " bcet: " << bcet_ << " wcet: " << wcet_ << " next_et: " << clock_exec_);
01470
01471 if (context_ == worstcase)
01472 context_ = branchingpoint;
01473
01474 next_et_ = clock_exec_;
01475 }
01476 }
01477 }
01478 }
01479 #endif
01480 }
01481
01482 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01483 void Task::consume ()
01484 throw (DREAM::Exception)
01485 #else
01486 inline void Task::consume ()
01487 #endif
01488 {
01489 if (state_ == idle)
01490 {
01491 thread_ptr_->enqueue (this);
01492 state_ = enabled;
01493 clock_dl_reset ();
01494 }
01495 else
01496 {
01497
01498 if (state_ != error)
01499 {
01500
01501 if (state_ != executing)
01502 thread_ptr_->dequeue (this);
01503 state_ = error;
01504 thread_ptr_->add_error (this);
01505 }
01506 }
01507 }
01508
01509 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01510 uint Task::deadline () const
01511 throw (DREAM::Exception)
01512 #else
01513 inline uint Task::deadline () const
01514 #endif
01515 {
01516 return deadline_;
01517 }
01518
01519 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01520 void Task::deadline (uint deadline)
01521 throw (DREAM::Exception)
01522 #else
01523 inline void Task::deadline (uint deadline)
01524 #endif
01525 {
01526 deadline_ = deadline;
01527 }
01528
01529 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01530 void Task::execute ()
01531 throw (DREAM::Exception)
01532 #else
01533 inline void Task::execute ()
01534 #endif
01535 {
01536 if ((state_ == enabled) || (state_ == preempted))
01537 {
01538 state_ = executing;
01539 thread_ptr_->dequeue (this);
01540 clock_exec_reset ();
01541
01542 std::string message;
01543 if (bcet_ != wcet_)
01544 {
01545 #ifdef DREAM_BRANCHING
01546 if (context_ == branchingpoint)
01547 {
01548 thread_ptr_->trace (message << "Branching point is taken by " << id_);
01549 }
01550 #endif
01551 thread_ptr_->trace (message << id_ << " p: " << priority ()
01552 << " sp: " << subpriority_ << " exec time: " << et_
01553 << " <-- [" << bcet_ << ", " << wcet_ << "]");
01554 }
01555 else
01556 {
01557 thread_ptr_->trace (message << id_ << " p: " << priority ()
01558 << " sp: " << subpriority_ << " exec time: " << et_ );
01559 }
01560 }
01561 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01562 else
01563 {
01564 std::string message;
01565 message << "Task " << id_ << " scheduled for execution is not enabled. Please report bug at http://sourceforge.net/projects/dre!";
01566 throw DREAM::Exception (message);
01567 }
01568 #endif
01569 }
01570
01571 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01572 bool Task::isidle () const
01573 throw (DREAM::Exception)
01574 #else
01575 inline bool Task::isidle () const
01576 #endif
01577 {
01578 return (state_ == idle) ? true : false;
01579 }
01580
01581 inline double Task::next_event ()
01582 {
01583
01584
01585 return (state_ == executing) ? et_ - clock_exec_ : 0.0;
01586 }
01587
01588 #ifdef DREAM_BRANCHING
01589 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01590 void Task::next_et (double next_et)
01591 throw (DREAM::Exception)
01592 #else
01593 inline void Task::next_et (double next_et)
01594 #endif
01595 {
01596 next_et_ = next_et;
01597 }
01598 #endif
01599
01600 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01601 void Task::preempt ()
01602 throw (DREAM::Exception)
01603 #else
01604 inline void Task::preempt ()
01605 #endif
01606 {
01607 if (state_ == executing) state_ = preempted;
01608 thread_ptr_->enqueue (this);
01609 }
01610
01611 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01612 uint Task::priority () const
01613 throw (DREAM::Exception)
01614 #else
01615 inline uint Task::priority () const
01616 #endif
01617 {
01618 return thread_ptr_->priority ();
01619 }
01620
01621 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01622 void Task::priority (uint priority)
01623 throw (DREAM::Exception)
01624 #else
01625 inline void Task::priority (uint priority)
01626 #endif
01627 {
01628 deploy (scheduler ()->get_thread (priority));
01629 }
01630
01631 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01632 void Task::publish ()
01633 throw (DREAM::Exception)
01634 #else
01635 inline void Task::publish ()
01636 #endif
01637 {
01638 if (state_ == executing)
01639 state_ = idle;
01640 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01641 else
01642 {
01643 std::string message;
01644 message << "Task::publish () called on \"" << id_ << "\" which is not executing. Please report bug at http://sourceforge.net/projects/dre!";
01645 throw DREAM::Exception (message);
01646 }
01647 #endif
01648
01649 dependent_map_->publish ();
01650 thread_ptr_->scheduler ()->system ()->relevant_event (true);
01651 }
01652
01653 inline void Task::reset ()
01654 {
01655 state_ = idle;
01656 executed (0);
01657 clock_dl_reset ();
01658 clock_exec_reset ();
01659 }
01660
01661 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01662 uint Task::subpriority () const
01663 throw (DREAM::Exception)
01664 #else
01665 inline uint Task::subpriority () const
01666 #endif
01667 {
01668 return subpriority_;
01669 }
01670
01671 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01672 void Task::subpriority (uint subpriority)
01673 throw (DREAM::Exception)
01674 #else
01675 inline void Task::subpriority (uint subpriority)
01676 #endif
01677 {
01678 subpriority_ = subpriority;
01679 }
01680
01681 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01682 void Task::take_transitions ()
01683 throw (DREAM::Exception)
01684 #else
01685 inline void Task::take_transitions ()
01686 #endif
01687 {
01688 #ifdef DREAM_VERBOSE2
01689
01690
01691
01692
01693
01694 #endif
01695
01696 if ((clock_dl_ < deadline_) || (deadline_ == 0))
01697 {
01698
01699
01700 if (clock_exec_ == et_)
01701 {
01702 if (state_ == executing)
01703 {
01704 publish ();
01705 clock_exec_reset ();
01706 clock_dl_reset ();
01707 executed (1);
01708
01709 thread_ptr_->freethread ();
01710
01711 #ifdef DREAM_VERBOSE2
01712 if (Option::verbose1_ && Option::verbose2_)
01713 {
01714 std::string message;
01715 thread_ptr_->trace (message << id_ << " has finished the execution");
01716 }
01717 #endif
01718
01719 }
01720 }
01721 }
01722 else
01723 {
01724
01725 if (state_ != error)
01726 {
01727 if (state_ != executing)
01728 thread_ptr_->dequeue (this);
01729
01730 state_ = error;
01731 thread_ptr_->add_error (this);
01732 }
01733 }
01734
01735 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01736 if (clock_exec_ > et_)
01737 {
01738 std::string message;
01739 message << "Execution clock value \"" << clock_exec_ << "\" in Task \"" << id_ << "\" is greater than the actual execution time \"" << et_
01740 << "\" (bcet: \"" << bcet_ << "\" wcet: \"" << wcet_
01741 << "\"). Most likely the execution time was set during simulation. Please report bug at http://sourceforge.net/projects/dre!";
01742 throw DREAM::Exception (message);
01743 }
01744 #endif
01745 }
01746
01747 void Task::visitor_if (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map, std::ofstream& f_stream)
01748 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01749 throw (DREAM::Exception)
01750 #endif
01751 {
01752 if ((scheduler ()->nonpreemptive ())|| (scheduler ()->highestpriority (this)))
01753 {
01754 DREAM::NODE_MAP::const_iterator task_iter, task_iter2;
01755 uint i = 0;
01756
01757
01758 for (task_iter = task_map->begin (); task_iter->first != id (); task_iter++)
01759 {
01760 ++i;
01761 }
01762
01763 f_stream << "/*\n * Task " << i << " - " << id_ << "\n *\n */\n" << std::endl;
01764
01765 f_stream << "process task_" << id_ << " (1);\n" << std::endl;
01766
01767 f_stream << "var ce clock public;\nvar cd clock public;\n" << std::endl;
01768
01769 f_stream << "state initial #start ;\n\tdeadline eager;\n\tinput event ();\n\tset cd := 0;\n"
01770 << "\ttask ({common}0).en[" << i << "] := true;\n\t\tnextstate wait;\nendstate;\n" << std::endl;
01771
01772 f_stream << "state wait;\n\tdeadline eager;\n\tprovided ({common}0).exec[" << i << "];\n\tset ce := 0;\n"
01773 << "\t\tnextstate run;\nendstate;\n" << std::endl;
01774
01775 f_stream << "state run;\n\tdeadline delayable;\n\twhen ce <= wcet" << i << " and ce >= bcet" << i << ";\n"
01776 << "\t\ttask ({common}0).en[" << i << "] := false;\n\t\treset ce;\n\t\treset cd;" << std::endl;
01777
01778 const DREAM::NODE_MAP* node_map = get_dependent_map ();
01779 const DREAM::NODE_MAP* node_map2;
01780
01781
01782 DREAM::NODE_MAP::const_iterator find_iter;
01783
01784 for (task_iter = node_map->begin (); task_iter != node_map->end (); task_iter++)
01785 {
01786 find_iter = task_map->find (task_iter->first);
01787 if (find_iter != task_map->end ())
01788 f_stream << "\t\toutput event () to {task_" << find_iter->first << "}0;\n";
01789 else
01790 {
01791 find_iter = channel_map->find (task_iter->first);
01792
01793
01794 if (find_iter->second)
01795 node_map2 = find_iter->second->get_dependent_map ();
01796
01797 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01798 else
01799 {
01800 std::string message;
01801 message << "Task " << task_iter->first << " has no Channel dependents. Incorrect model.";
01802 throw DREAM::Exception (message);
01803 }
01804 #endif
01805
01806 for (task_iter2 = node_map2->begin (); task_iter2 != node_map2->end (); task_iter2++)
01807 {
01808 find_iter = node_map2->find (task_iter2->first);
01809
01810 if (find_iter != node_map2->end ())
01811 {
01812 if (task_iter->second->wcet () != 0)
01813 f_stream << "\t\toutput event () via {" << task_iter->first << "}0 to {task_" << find_iter->first << "}0;\n";
01814 else
01815 f_stream << "\t\toutput event () /* via {" << task_iter->first << "}0 */ to {task_" << find_iter->first << "}0;\n";
01816 }
01817
01818 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01819 else
01820 {
01821 std::string message;
01822 message << "Node " << task_iter2->first << " could not be found as a Task dependent in the Task list when generating IF input. Incorrect model.";
01823 throw DREAM::Exception (message);
01824 }
01825 #endif
01826
01827 }
01828 }
01829 }
01830
01831 f_stream << "\t\t\tnextstate initial;\n\tdeadline eager;\n\tprovided ({common}0).exec[" << i << "] = false;\n"
01832
01833 << "\twhen ce = 0;\n\t\tnextstate wait;\nendstate;\n\nendprocess;\n" << std::endl;
01834 }
01835 else
01836 {
01837 DREAM::NODE_MAP::const_iterator task_iter, task_iter2;
01838 uint i = 0;
01839
01840
01841 for (task_iter = task_map->begin (); task_iter->first != id (); task_iter++)
01842 {
01843 ++i;
01844 }
01845
01846 f_stream << "/*\n * Task " << i << " - " << id_ << "\n *\n */\n" << std::endl;
01847
01848 f_stream << "process task_" << id_ << " (1);\n" << std::endl;
01849
01850 f_stream << "var ce clock public;\nvar cd clock public;\nvar et integer public;\nvar pre integer public;\n" << std::endl;
01851
01852 f_stream << "state initial #start ;\n\tdeadline eager;\n\tinput event ();\n\tset cd := 0;\n\ttask et := 0;\n\ttask pre := 0;\n"
01853 << "\ttask ({common}0).en[" << i << "] := true;\n\t\tnextstate wait;\nendstate;\n" << std::endl;
01854
01855 f_stream << "state wait;\n\tdeadline eager;\n\tprovided ({common}0).exec[" << i << "];\n\tset ce := 0;\n"
01856 << "\t\tnextstate run;\nendstate;\n" << std::endl;
01857
01858
01859
01860
01861 f_stream << "state run;\n\tdeadline delayable;\n\twhen ce >= bcet" << i << " - et - pre;\n"
01862 << "\t\ttask ({common}0).en[" << i << "] := false;\n\t\treset ce;\n\t\treset cd;" << std::endl;
01863
01864 const DREAM::NODE_MAP* node_map = get_dependent_map ();
01865 const DREAM::NODE_MAP* node_map2;
01866
01867
01868 DREAM::NODE_MAP::const_iterator find_iter;
01869
01870 for (task_iter = node_map->begin (); task_iter != node_map->end (); task_iter++)
01871 {
01872 find_iter = task_map->find (task_iter->first);
01873 if (find_iter != task_map->end ())
01874 f_stream << "\t\toutput event () to {task_" << find_iter->first << "}0;\n";
01875 else
01876 {
01877 find_iter = channel_map->find (task_iter->first);
01878
01879
01880 if (find_iter->second)
01881 node_map2 = find_iter->second->get_dependent_map ();
01882
01883 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01884 else
01885 {
01886 std::string message;
01887 message << "Task " << task_iter->first << " has no Channel dependents. Incorrect model.";
01888 throw DREAM::Exception (message);
01889 }
01890 #endif
01891
01892 for (task_iter2 = node_map2->begin (); task_iter2 != node_map2->end (); task_iter2++)
01893 {
01894 find_iter = node_map2->find (task_iter2->first);
01895 if (find_iter != node_map2->end ())
01896 {
01897 if (task_iter->second->wcet () != 0)
01898 f_stream << "\t\toutput event () via {" << task_iter->first << "}0 to {task_" << find_iter->first << "}0;\n";
01899 else
01900 f_stream << "\t\toutput event () /* via {" << task_iter->first << "}0 */ to {task_" << find_iter->first << "}0;\n";
01901 }
01902
01903 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01904 else
01905 {
01906 std::string message;
01907 message << "Node " << task_iter2->first << " could not be found as a Task dependent in the Task list when generating IF input. Incorrect model.";
01908 throw DREAM::Exception (message);
01909 }
01910 #endif
01911 }
01912 }
01913 }
01914
01915
01916
01917
01918 f_stream << "\t\t\tnextstate initial;\n\tdeadline eager;\n\twhen ce >= wcet" << i << " - et;\n"
01919 << "\t\ttask ({common}0).en[" << i << "] := false;\n\t\treset ce;\n\t\treset cd;" << std::endl;
01920
01921
01922
01923
01924
01925 for (task_iter = node_map->begin (); task_iter != node_map->end (); task_iter++)
01926 {
01927 find_iter = task_map->find (task_iter->first);
01928 if (find_iter != task_map->end ())
01929 f_stream << "\t\toutput event () to {task_" << find_iter->first << "}0;\n";
01930 else
01931 {
01932 find_iter = channel_map->find (task_iter->first);
01933
01934
01935 if (find_iter->second)
01936 node_map2 = find_iter->second->get_dependent_map ();
01937
01938 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01939 else
01940 {
01941 std::string message;
01942 message << "Task " << task_iter->first << " has no Channel dependents. Incorrect model.";
01943 throw DREAM::Exception (message);
01944 }
01945 #endif
01946
01947 for (task_iter2 = node_map2->begin (); task_iter2 != node_map2->end (); task_iter2++)
01948 {
01949 find_iter = node_map2->find (task_iter2->first);
01950 if (find_iter != node_map2->end ())
01951 {
01952 if (task_iter->second->wcet () != 0)
01953 f_stream << "\t\toutput event () via {" << task_iter->first << "}0 to {task_" << find_iter->first << "}0;\n";
01954 else
01955 f_stream << "\t\toutput event () /* via {" << task_iter->first << "}0 */ to {task_" << find_iter->first << "}0;\n";
01956 }
01957
01958 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01959 else
01960 {
01961 std::string message;
01962 message << "Node " << task_iter2->first << " could not be found as a Channel dependent in the Task list when generating IF input. Incorrect model.";
01963 throw DREAM::Exception (message);
01964 }
01965 #endif
01966 }
01967 }
01968 }
01969
01970 f_stream << "\t\t\tnextstate initial;\n\tprovided et + pr < wcet" << i << ";\n\twhen ce >= pr;\n\t\tnextstate pass;\n"
01971 << "\tprovided ({common}0).exec[" << i << "] = false and et = 0;\n"
01972
01973
01974
01975
01976
01977 << "\twhen ce = 0;\n\t\tnextstate wait;\n\tprovided ({common}0).exec[" << i << "] = false and et = 0;\n"
01978 << "\twhen ce > 0;\n\ttask pre := pre + pr;\n\t\tnextstate wait;\n"
01979 << "\tprovided ({common}0).exec[" << i << "] = false and et > 0;\n\ttask pre := pre + pr;\n\t\tnextstate wait;\n"
01980 << "\nendstate;\n\nstate pass #unstable ;\n\tset ce := 0;\n\ttask et := et + pr;\n\t\tnextstate run;\nendstate;\n"
01981 << "\nendprocess;\n" << std::endl;
01982
01983
01984
01985
01986 }
01987 }
01988
01989 void Task::visitor_map (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map)
01990 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01991 throw (DREAM::Exception)
01992 #endif
01993 {
01994 task_map->insert (DREAM::NODE_PAIR (id_, this));
01995 }
01996
01997 void Task::visitor_task_avltree (DREAM::TASK_AVLTREE* task_avltree)
01998 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
01999 throw (DREAM::Exception)
02000 #endif
02001 {
02002 task_avltree->insert (id_, this);
02003 }
02004
02005 void Task::visitor_update_task_avltree (DREAM::TASK_AVLTREE* task_avltree)
02006 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02007 throw (DREAM::Exception)
02008 #endif
02009 {
02010 DREAM::TASK_AVLTREE::iterator task_iter;
02011
02012
02013 for (task_iter = task_avltree->begin ();
02014 task_iter != task_avltree->end (); task_iter++)
02015 {
02016 if (this == (*task_iter)->second)
02017
02018 break;
02019 if ((*this) == * ((*task_iter)->second))
02020 {
02021 (*this) = * ((*task_iter)->second);
02022 break;
02023 }
02024 }
02025 }
02026
02027 void Task::visitor_uppaal (DREAM::NODE_MAP* task_map, DREAM::NODE_MAP* channel_map, DREAM::NODE_MAP* timer_map, std::ofstream& f_stream)
02028 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02029 throw (DREAM::Exception)
02030 #endif
02031 {
02032 if ((scheduler ()->nonpreemptive ())|| (scheduler ()->highestpriority (this)))
02033 f_stream << id () << " := NonpTask (";
02034 else
02035 f_stream << id () << " := Task (";
02036
02037 DREAM::NODE_MAP::const_iterator task_iter;
02038 uint i = 0;
02039
02040
02041 for (task_iter = task_map->begin (); task_iter->first != id_; task_iter++)
02042 {
02043 ++i;
02044 }
02045
02046 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02047 if (task_iter == task_map->end ())
02048 throw DREAM::Exception ("Task::visitor_uppaal () called for a nonexistent Task. Please report bug at http://sourceforge.net/projects/dre!");
02049 #endif
02050
02051 if ((scheduler ()->nonpreemptive ())|| (scheduler ()->highestpriority (this)))
02052 f_stream << i << ", " << wcet_ << ", " << bcet_ << ", " << deadline_ << ", ";
02053 else
02054 f_stream << i << ", " << wcet_ << ", " << bcet_ << ", " << deadline_ << ", 1, ";
02055
02056 if (get_source (task_map, channel_map, timer_map))
02057
02058 f_stream << "publish" << get_source (task_map, channel_map, timer_map)->id () ;
02059 else
02060
02061 f_stream << "start" << id ();
02062
02063 if ((scheduler ()->nonpreemptive ())|| (scheduler ()->highestpriority (this)))
02064 f_stream << ", run" << id () << ", publish" << id () << ");" << std::endl;
02065 else
02066 f_stream << ", run" << id () << ", publish" << id () << ", preempt"
02067 << scheduler ()->id () << ");" << std::endl;
02068 }
02069
02070 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02071 uint Task::wcet () const
02072 throw (DREAM::Exception)
02073 #else
02074 inline uint Task::wcet () const
02075 #endif
02076 {
02077 return wcet_;
02078 }
02079
02080 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02081 void Task::wcet (uint wcet)
02082 throw (DREAM::Exception)
02083 #else
02084 inline void Task::wcet (uint wcet)
02085 #endif
02086 {
02087 wcet_ = wcet;
02088 }
02089
02090 #ifndef DREAM_RACE_CONDITION_ZERO
02091 bool Task::zero_delay_race_condition (DREAM::System* system_ptr)
02092 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02093 throw (DREAM::Exception)
02094 #endif
02095 {
02096 if (!Option::race_condition_zero_)
02097 {
02098 if (zero_delay_race_condition_ == 0)
02099 return false;
02100 else if (zero_delay_race_condition_ == 1)
02101 return true;
02102
02103 DREAM::NODE_MAP task_map;
02104 DREAM::NODE_MAP channel_map;
02105 DREAM::NODE_MAP timer_map;
02106
02107 system_ptr->visitor_map (&task_map, &channel_map, &timer_map);
02108
02109 const DREAM::Node* source_task = get_source (&task_map, &channel_map, &timer_map);
02110
02111 if ((source_task) && (scheduler ()) && (source_task->scheduler ()))
02112 {
02113 if (scheduler () == source_task->scheduler ())
02114 {
02115
02116
02117 zero_delay_race_condition_ = 1;
02118 return true;
02119 }
02120 else
02121 {
02122 zero_delay_race_condition_ = 0;
02123 return false;
02124 }
02125 }
02126 else
02127 {
02128
02129 DREAM::NODE_MAP::const_iterator node_iter;
02130 bool found = false;
02131 bool allzero = true;
02132
02133 for (node_iter = channel_map.begin (); node_iter != channel_map.end (); node_iter++)
02134 {
02135 if (node_iter->second->get_dependent (id_))
02136 {
02137 found = true;
02138 if (node_iter->second->wcet () != 0)
02139 allzero = false;
02140 }
02141 }
02142
02143 if (found && allzero)
02144 {
02145 zero_delay_race_condition_ = 1;
02146 return true;
02147 }
02148 else
02149 {
02150 zero_delay_race_condition_ = 0;
02151 return false;
02152 }
02153 }
02154 }
02155 else
02156 return false;
02157 }
02158 #endif
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 #ifdef DREAM_RACE_CONDITION
02249 PriorityInversionList::PriorityInversionList (DREAM::System* system_ptr)
02250 : system_ptr_ (system_ptr)
02251 {
02252 }
02253
02254 PriorityInversionList::~PriorityInversionList ()
02255 {
02256 task_avltree_list_.destroy ();
02257 }
02258
02259 void PriorityInversionList::add (const DREAM::TASK_AVLTREE* task_avltree_ptr, DREAM::Task* task_ptr)
02260 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02261 throw (DREAM::Exception)
02262 #endif
02263 {
02264 DREAM::TASK_AVLTREE* new_avltree = NULL;
02265
02266 if (!find (task_avltree_ptr, task_ptr))
02267 {
02268
02269
02270
02271 new_avltree = new DREAM::TASK_AVLTREE ();
02272 task_avltree_list_.push_back (new_avltree);
02273
02274 new_avltree->assign (task_avltree_ptr->begin (), task_avltree_ptr->end ());
02275 task_id_list_.push_back (new_avltree->begin ()->first);
02276 }
02277 }
02278
02279 void PriorityInversionList::destroy ()
02280
02281 {
02282
02283 task_avltree_list_.destroy ();
02284 task_id_list_.clear ();
02285 }
02286
02287 DREAM::Task* PriorityInversionList::find (const DREAM::TASK_AVLTREE* task_avltree_ptr, DREAM::Task* task_ptr)
02288 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02289 throw (DREAM::Exception)
02290 #endif
02291 {
02292 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02293 if (!task_ptr)
02294 throw DREAM::Exception ("Illegal use of PriorityInversionList::find (). Please report bug at http://sourceforge.net/projects/dre!");
02295 #endif
02296
02297 TASK_AVLTREE_LIST::const_iterator main_iter;
02298 TASK_ID_LIST::const_iterator id_iter;
02299 bool found = false;
02300 id_iter = NULL;
02301
02302
02303
02304 for (main_iter = task_avltree_list_.begin (); main_iter != task_avltree_list_.end (); main_iter++)
02305 {
02306
02307 if (id_iter == NULL)
02308 id_iter = task_id_list_.begin ();
02309 else
02310 ++id_iter;
02311
02312 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02313 if (id_iter == task_id_list_.end ())
02314 throw DREAM::Exception ("PriorityInversionList::find () task_avltree_ptr_ and task_id_list_ lists are out of sync. Please report bug at http://sourceforge.net/projects/dre!");
02315 #endif
02316
02317
02318 if (main_iter->item ()->size () != task_avltree_ptr->size ())
02319
02320 break;
02321
02322
02323 DREAM::TASK_AVLTREE::const_iterator tree_iter;
02324 for (tree_iter = task_avltree_ptr->begin (); tree_iter != task_avltree_ptr->end (); tree_iter++)
02325 {
02326 if (main_iter->item ()->find (tree_iter->first) == main_iter->item ()->end ())
02327
02328 break;
02329
02330
02331 return main_iter->item ()->find (id_iter->item ())->second;
02332 }
02333 }
02334
02335 return NULL;
02336 }
02337
02338 DREAM::Task* PriorityInversionList::find_current (const DREAM::TASK_AVLTREE* task_avltree_ptr, DREAM::Task* task_ptr)
02339
02340 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
02341 throw (DREAM::Exception)
02342 #endif
02343 {
02344 add (task_avltree_ptr, task_ptr);
02345 return (find (task_avltree_ptr, task_ptr));
02346 }
02347
02348 bool PriorityInversionList::increment (TASK_AVLTREE_LIST::iterator task_avltree_list_iter,
02349 TASK_ID_LIST::iterator task_id_list_iter)
02350 {
02351 AVLTree <std::string, DREAM::Task*>* tree_ptr = task_avltree_list_iter->item ();
02352 AVLTreeNode <std::string, DREAM::Task*>* node_ptr = tree_ptr->find (task_id_list_iter->item ());
02353 TASK_AVLTREE::iterator iter;
02354 iter = node_ptr;
02355
02356 if (iter != task_avltree_list_iter->item ()->last ())
02357 {
02358
02359 iter++;
02360
02361 task_id_list_iter->item (iter->first);
02362 return true;
02363 }
02364 else
02365 {
02366
02367 #ifdef DREAM_RACE_CONDITION_COMBINATION
02368 if ((Option::race_condition_combination_) && (Option::race_condition_))
02369 {
02370
02371 task_id_list_iter->item (task_avltree_list_iter->item ()->begin ()->first);
02372 }
02373 #endif
02374
02375 ++task_avltree_list_iter;
02376 ++task_id_list_iter;
02377 if ((task_avltree_list_iter != task_avltree_list_.end ()) && (task_id_list_iter != task_id_list_.end ()))
02378 {
02379 return increment (task_avltree_list_iter, task_id_list_iter);
02380 }
02381 else
02382 return false;
02383 }
02384 }
02385
02386 bool PriorityInversionList::inversion ()
02387
02388 {
02389 if (task_avltree_list_.size () == 0)
02390 return false;
02391
02392 TASK_AVLTREE_LIST::iterator tree_iter;
02393 TASK_ID_LIST::iterator id_iter;
02394 tree_iter = task_avltree_list_.begin ();
02395 id_iter = task_id_list_.begin ();
02396
02397 return increment (tree_iter, id_iter);
02398 }
02399
02400 #endif
02401
02402 }