diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp | 932 |
1 files changed, 0 insertions, 932 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp b/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp deleted file mode 100644 index 86eb472f625..00000000000 --- a/TAO/orbsvcs/orbsvcs/Sched/SchedEntry.cpp +++ /dev/null @@ -1,932 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// sched -// -// = FILENAME -// SchedEntry.cpp -// -// = CREATION DATE -// 7 February 1998 -// -// = AUTHOR -// Chris Gill -// -// ============================================================================ - -#include "SchedEntry.h" - -#if ! defined (__ACE_INLINE__) -#include "SchedEntry.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(Sched, SchedEntry, "$Id$") - -Task_Entry::Task_Entry (void) - : rt_info_ (0), - effective_period_(0), - dfs_status_ (NOT_VISITED), - discovered_ (-1), - finished_ (-1), - is_thread_delineator_ (0), - has_unresolved_remote_dependencies_ (0), - has_unresolved_local_dependencies_ (0), - calls_ (), - callers_ () -{ -} - -Task_Entry::~Task_Entry (void) -{ - // Zero out the task entry ACT in the corresponding rt_info - rt_info_->volatile_token = 0; - - ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter(calls_); - Task_Entry_Link **link = 0; - - // Iterate through the "calls" set of Task Entry Links and free each one - - for (iter.first (); - ! iter.done (); - iter.advance (), link = 0) - { - if (iter.next (link) != 0 && link != 0 && *link != 0) - { - // remove the link object pointer from the calling entry's - // "callers" set and destroy the link object - (*link)->called ().callers_.remove (*link); - delete (*link); - } - } -} - -// Merge dispatches according to info type and type of call, update -// relevant scheduling characteristics for this entry. - -Task_Entry::Propagation_Status -Task_Entry::merge_dispatches (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, - ACE_CString &unresolved_locals, - ACE_CString &unresolved_remotes) -{ - Task_Entry::Propagation_Status result = SUCCEEDED; - switch (info_type ()) - { - case RtecScheduler::DISJUNCTION: - - // Prohibit two-way dispatches of a disjunction group, and - // disjunctively merge its one-way dispatches. NOTE: one - // interpretation of disjunction for two-way calls is that the - // caller calls one OR the other, but this is problematic: how - // do we map the dispatches for this ? - if (prohibit_dispatches (RtecScheduler::TWO_WAY_CALL) < 0) - result = TWO_WAY_DISJUNCTION; - - if (disjunctive_merge (RtecScheduler::ONE_WAY_CALL, - dispatch_entries, - unresolved_locals, - unresolved_remotes) < 0) - result = INTERNAL_ERROR; - break; - - case RtecScheduler::CONJUNCTION: - - // Prohibit two-way dispatches of a conjunction group, - // and conjunctively merge its one-way dispatches. - // NOTE: one interpretation of disjunction for two-way calls - // is that the caller calls BOTH, so that there is a - // disjunctive merge of each two-way, as for the OPERATION - // (prohibit for now, as the additional complexity of allowing - // conjunctions of two-ways, but not disjunctions does not - // buy us anything, anyway). - if (prohibit_dispatches (RtecScheduler::TWO_WAY_CALL) < 0) - result = TWO_WAY_CONJUNCTION; - if (conjunctive_merge (RtecScheduler::ONE_WAY_CALL, - dispatch_entries, - unresolved_locals, - unresolved_remotes) < 0) - result = INTERNAL_ERROR; - break; - - case RtecScheduler::OPERATION: - case RtecScheduler::REMOTE_DEPENDANT: - - // Disjunctively merge the operation's two-way dispatches, and - // conjunctively merge its one-way dispatches. - if (disjunctive_merge (RtecScheduler::TWO_WAY_CALL, - dispatch_entries, - unresolved_locals, - unresolved_remotes) < 0) - result = INTERNAL_ERROR; - if (conjunctive_merge (RtecScheduler::ONE_WAY_CALL, - dispatch_entries, - unresolved_locals, - unresolved_remotes) < 0) - result = INTERNAL_ERROR; - break; - - default: - - // There should not be any other kind of RT_Info, or if there - // is, the above switch logic is in need of repair. - result = UNRECOGNIZED_INFO_TYPE; - break; - } - - return result; -} - -// Prohibit calls of the given type: currently used to enforce the -// notion that two-way calls to disjunctive or conjunctive RT_Infos do -// not have any defined meaning, and thus should be considered -// dependency specification errors: if these constraints are removed -// in the future, this method should be removed as well Returns 0 if -// all is well, or -1 if an error has occurred. - -int -Task_Entry::prohibit_dispatches (Dependency_Type dt) -{ - // Iterate over the set of dependencies, ensuring none of them has - // the given dependency type. - for (ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter (callers_); - ! iter.done (); - iter.advance ()) - { - Task_Entry_Link **link; - - if (iter.next (link) == 0 - || link == 0 - || *link == 0 - || (*link)->dependency_type () == dt) - return -1; - } - - return 0; -} - -// Perform disjunctive merge of arrival times of oneway calls: all -// arrival times of all dependencies are duplicated by the multiplier -// and repetition over the new frame size. - -int -Task_Entry::disjunctive_merge (Dependency_Type dt, - ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, - ACE_CString &unresolved_locals, - ACE_CString &unresolved_remotes) -{ - char string_buffer[BUFSIZ]; - - // Iterate over the set of dependencies, merging dispatches of the - // callers over the enclosing frame size. - for (ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter (callers_); - ! iter.done (); - iter.advance ()) - { - Task_Entry_Link **link; - - if (iter.next (link) == 0 - || link == 0 - || *link == 0) - return -1; - - // The link matches the dependency type given - if ((*link)->dependency_type () == dt) - { - // Check for and warn about unresolved remote dependencies - // in the ONE_WAY call graph. - if ((*link)->dependency_type () == RtecScheduler::ONE_WAY_CALL - && (*link)->caller ().has_unresolved_remote_dependencies () - && ! this->has_unresolved_remote_dependencies ()) - { - // Propagate the unresolved remote dependency flag, and - // issue a debug scheduler warning. - this->has_unresolved_remote_dependencies (1); - ACE_DEBUG ((LM_DEBUG, - "Warning: an operation identified by " - "\"%s\" has unresolved remote dependencies.\n", - (const char*) this->rt_info ()->entry_point)); - - // Record entry point in list of unresolved remote - // dependencies - ACE_OS::sprintf (string_buffer, - "// %s\n", - (const char*) this->rt_info ()->entry_point); - unresolved_remotes += - ACE_CString (string_buffer); - - } - - // Check for and warn about unresolved local dependencies in - // the ONE_WAY call graph. - if ((*link)->dependency_type () == RtecScheduler::ONE_WAY_CALL - && (*link)->caller ().has_unresolved_local_dependencies () - && ! this->has_unresolved_local_dependencies ()) - { - // Propagate the unresolved local dependency flag, and - // issue a debug scheduler warning. - this->has_unresolved_local_dependencies (1); - ACE_DEBUG ((LM_DEBUG, - "Warning: an operation identified by " - "\"%s\" has unresolved local dependencies.\n", - (const char*) this->rt_info ()->entry_point)); - - // Record entry point in list of unresolved local - // dependencies - ACE_OS::sprintf (string_buffer, - "// %s\n", - (const char*) this->rt_info ()->entry_point); - unresolved_locals += - ACE_CString (string_buffer); - } - - // Merge the caller's dispatches into the current set. - if (merge_frames (dispatch_entries, - *this, - dispatches_, - (*link)->caller ().dispatches_, effective_period_, - (*link)->caller ().effective_period_, - (*link)->number_of_calls ()) < 0) - return -1; - } - } - - return 0; -} - -// Perform conjunctive merge of arrival times of calls: all arrival -// times of all dependencies are duplicated by the multiplier and -// repetition over the new frame size and then iteratively merged by -// choosing the maximal arrival time at the current position in each -// queue (iteration is in lockstep over all queues, and ends when any -// queue ends). - -int -Task_Entry::conjunctive_merge (Dependency_Type dt, - ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, - ACE_CString &unresolved_locals, - ACE_CString &unresolved_remotes) -{ - int result = 0; - char string_buffer [BUFSIZ]; - - // Iterate over the dependencies, and determine the total frame - // size. - - u_long frame_size = 1; - - ACE_Unbounded_Set_Iterator <Task_Entry_Link *> dep_iter (callers_); - - for (dep_iter.first (); - dep_iter.done () == 0; - dep_iter.advance ()) - { - Task_Entry_Link **link; - - if (dep_iter.next (link) == 0 - || link == 0 - || *link == 0) - return -1; - - // The link matches the dependency type given. - if ((*link)->dependency_type () == dt) - { - // Check for and warn about unresolved remote dependencies - // in the ONE_WAY call graph. - if ((*link)->dependency_type () == RtecScheduler::ONE_WAY_CALL - && (*link)->caller ().has_unresolved_remote_dependencies () - && ! this->has_unresolved_remote_dependencies ()) - { - // Propagate the unresolved remote dependency flag, and - // issue a debug scheduler warning. - this->has_unresolved_remote_dependencies (1); - ACE_DEBUG ((LM_DEBUG, - "Warning: an operation identified by " - "\"%s\" has unresolved remote dependencies.\n", - (const char*) this->rt_info ()->entry_point)); - - // Record entry point in list of unresolved remote - // dependencies - ACE_OS::sprintf (string_buffer, - "// %s\n", - (const char*) this->rt_info ()->entry_point); - unresolved_remotes += - ACE_CString (string_buffer); - } - - // Check for and warn about unresolved local dependencies in - // the ONE_WAY call graph. - if ((*link)->dependency_type () == RtecScheduler::ONE_WAY_CALL - && (*link)->caller ().has_unresolved_local_dependencies () - && ! this->has_unresolved_local_dependencies ()) - { - // Propagate the unresolved local dependency flag, and - // issue a debug scheduler warning. - this->has_unresolved_local_dependencies (1); - ACE_DEBUG ((LM_DEBUG, - "Warning: an operation identified by " - "\"%s\" has unresolved local dependencies.\n", - (const char*) this->rt_info ()->entry_point)); - - // Record entry point in list of unresolved local dependencies - ACE_OS::sprintf (string_buffer, - "// %s\n", - (const char*) this->rt_info ()->entry_point); - unresolved_locals += - ACE_CString (string_buffer); - } - - frame_size = ACE::minimum_frame_size (frame_size, - (*link)->caller ().effective_period_); - } - } - - // Reframe dispatches in the set to the new frame size (expands the - // set's effective period to be the new enclosing frame). - if (reframe (dispatch_entries, - *this, dispatches_, - effective_period_, - frame_size) < 0) - return -1; - - // A container and iterator for virtual dispatch sets over which the - // conjunction will operate - ACE_Ordered_MultiSet <Dispatch_Proxy_Iterator *> conj_set; - ACE_Ordered_MultiSet_Iterator <Dispatch_Proxy_Iterator *> conj_set_iter (conj_set); - - // Iterate over the dependencies, and for each of the given call - // type, create a Dispatch_Proxy_Iterator for the caller's dispatch - // set, using the caller's period, the total frame size, and the - // number of calls: if any of the sets is empty, just return 0; - for (dep_iter.first (); - dep_iter.done () == 0; - dep_iter.advance ()) - { - Task_Entry_Link **link; - if (dep_iter.next (link) == 0 - || link == 0 - || *link == 0) - return -1; - - // The link matches the dependency type given. - if ((*link)->dependency_type () == dt) - { - Dispatch_Proxy_Iterator *proxy_ptr; - ACE_NEW_RETURN (proxy_ptr, - Dispatch_Proxy_Iterator ((*link)->caller ().dispatches_, - (*link)->caller ().effective_period_, - frame_size, - (*link)->number_of_calls ()), - -1); - - // If there are no entries in the virtual set, we're done. - if (proxy_ptr->done ()) - return 0; - else if (conj_set.insert (proxy_ptr, conj_set_iter) < 0) - return -1; - } - } - - // loop, adding conjunctive dispatches, until one of the conjunctive - // dispatch sources runs out of entries over the total frame - conj_set_iter.first (); - int more_dispatches = (conj_set_iter.done ()) ? 0 : 1; - while (more_dispatches) - { - Time arrival = 0; - Time deadline = 0; - Preemption_Priority priority = 0; - OS_Priority OS_priority = 0; - - for (conj_set_iter.first (); - conj_set_iter.done () == 0; - conj_set_iter.advance ()) - { - // initialize to earliest arrival and deadline, and highest priority - arrival = 0; - deadline = 0; - priority = 0; - OS_priority = 0; - - // Policy: conjunctively dispatched operations get the - // latest deadline of any of the dispatches in the - // conjunction at the time they were dispatched - when and - // if it is useful to change any of the merge policies, this - // should be one of the decisions factored out into the - // conjunctive merge strategy class. - - // Policy: conjunctively dispatched operations get the - // lowest priority of any of the dispatches in the - // conjunction at the time they were dispatched - when and - // if it is useful to change any of the merge policies, this - // should be one of the decisions factored out into the - // conjunctive merge strategy class. - - // Obtain a pointer to the current dispatch proxy iterator. - Dispatch_Proxy_Iterator **proxy_iter; - if (conj_set_iter.next (proxy_iter) == 0 - || proxy_iter == 0 - || *proxy_iter == 0) - return -1; - - // Use latest arrival, latest deadline, lowest priority (0 is highest). - if (arrival <= (*proxy_iter)->arrival ()) - arrival = (*proxy_iter)->arrival (); - if (deadline <= (*proxy_iter)->deadline ()) - deadline = (*proxy_iter)->deadline (); - if (priority <= (*proxy_iter)->priority ()) - { - priority = (*proxy_iter)->priority (); - OS_priority = (*proxy_iter)->OS_priority (); - } - - (*proxy_iter)->advance (); - - if ((*proxy_iter)->done ()) - more_dispatches = 0; - } - - Dispatch_Entry *entry_ptr; - ACE_NEW_RETURN (entry_ptr, - Dispatch_Entry (arrival, - deadline, - priority, - OS_priority, - *this), - -1); - - // If even one new dispatch was inserted, result is "something - // happened". - result = 1; - - // Add the new dispatch entry to the set of all dispatches, and - // a link to it to the dispatch links for this task entry. - if (dispatch_entries.insert (entry_ptr) < 0) - return -1; - - // Use iterator for efficient insertion into the dispatch set. - ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> insert_iter (dispatches_); - if (dispatches_.insert (Dispatch_Entry_Link (*entry_ptr), - insert_iter) < 0) - return -1; - - // TBD - Clients are not assigned priority, but rather obtain it - // from their call dependencies. We could complain here if - // there is a priority specified that doesn't match (or is lower - // QoS?) - } - - return result; -} - -// This static method is used to reframe an existing dispatch set to -// the given new period multiplier, creating new instances of each -// existing dispatch (with adjusted arrival and deadline) in each -// successive sub-frame. Returns 1 if the set was reframed to a new -// period, 0 if the set was not changed (the new period was not a -// multiple of the old one), or -1 if an error occurred. - -int -Task_Entry::reframe (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, - Task_Entry &owner, - ACE_Ordered_MultiSet <Dispatch_Entry_Link> &set, - u_long &set_period, u_long new_period) -{ - int result = 0; - - // if the set period is zero, treat it as uninitialized, - // and simply value the set period with the new period - if (set_period) - { - // make sure the new period is greater than the current - // set period, and that they are harmonically related - if (new_period <= set_period) - // return an error if they're not harmonically related, - // do nothing if set's frame is a multiple of the new frame - return (set_period % new_period) ? -1 : 0; - else if (new_period % set_period) - return -1; - - // make a shallow copy of the set in a new ordered multiset - // using the Dispatch_Entry_Link smart pointers - ACE_Ordered_MultiSet <Dispatch_Entry_Link> new_set; - ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> new_iter (new_set); - ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> set_iter (set); - - for (set_iter.first (); set_iter.done () == 0; set_iter.advance ()) - { - Dispatch_Entry_Link *link; - - if (set_iter.next (link) == 0) - return -1; - else if (new_set.insert (*link, new_iter) < 0) - return -1; - } - - // Do a deep copy merge back into the set using the new period - // and starting after the 0th sub-frame: this puts all - // dispatches after the 0th sub-frame of the new period into the - // set, and leaves existing dispatches in the 0th sub-frame of - // the new period in the set as well. - result = merge_frames (dispatch_entries, - owner, - set, - new_set, - new_period, - set_period, - 1, - 1); - } - - // update the set's period to be the new frame - set_period = new_period; - - return result; -} - -// This static method is used to merge an existing dispatch set, -// multiplied by the given multipliers for the period and number of -// instances in each period of each existing dispatch, into the given -// "into" set, without affecting the "from set". - -int -Task_Entry::merge_frames (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries, - Task_Entry &owner, - ACE_Ordered_MultiSet <Dispatch_Entry_Link> &dest, - ACE_Ordered_MultiSet <Dispatch_Entry_Link> &src, - u_long &dest_period, - u_long src_period, - u_long number_of_calls, - u_long starting_dest_sub_frame) -{ - int status = 0; - - // reframe dispatches in the destination set to the new frame size - // (expands the destination set's period to be the new enclosing frame) - if (reframe (dispatch_entries, - owner, - dest, - dest_period, - ACE::minimum_frame_size (dest_period, - src_period)) < 0) - return -1; - - // use iterator for efficient insertion into the destination set - ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> dest_iter (dest); - - // do virtual iteration over the source set in the new frame, adding - // adjusted dispatch entries to the destination - Dispatch_Proxy_Iterator src_iter (src, - src_period, - dest_period, - number_of_calls, - starting_dest_sub_frame); - - for (src_iter.first (starting_dest_sub_frame); - src_iter.done () == 0; - src_iter.advance ()) - { - // Policy: disjunctively dispatched operations get their - // deadline and priority from the original dispatch - when and - // if it is useful to change any of the merge policies, this - // should be one of the decisions factored out into the - // disjunctive merge strategy class. - - Dispatch_Entry *entry_ptr; - ACE_NEW_RETURN (entry_ptr, - Dispatch_Entry (src_iter.arrival (), - src_iter.deadline (), - src_iter.priority (), - src_iter.OS_priority (), - owner), - -1); - - // if even one new dispatch was inserted, status is "something happened". - status = 1; - - // add the new dispatch entry to the set of all dispatches, and - // a link to it to the dispatch links for this task entry - if (dispatch_entries.insert (entry_ptr) < 0) - return -1; - - else if (dest.insert (Dispatch_Entry_Link (*entry_ptr), dest_iter) < 0) - return -1; - - // TBD - Clients are not assigned priority, but rather obtain it - // from their call dependencies. We could complain here if - // there is a priority specified that doesn't match (or is lower - // QoS?) - } - - return status; -} - -Task_Entry_Link::Task_Entry_Link (Task_Entry &caller, - Task_Entry &called, - CORBA::Long number_of_calls, - RtecScheduler::Dependency_Type_t dependency_type) - : number_of_calls_ (number_of_calls), - caller_ (caller), - called_ (called), - dependency_type_ (dependency_type) -{ -} - -Dispatch_Entry::Dispatch_Id Dispatch_Entry::next_id_ = 0; - -Dispatch_Entry::Dispatch_Entry (Time arrival, - Time deadline, - Preemption_Priority priority, - OS_Priority os_priority, - Task_Entry &task_entry, - Dispatch_Entry *original_dispatch) - : priority_ (priority), - OS_priority_ (os_priority), - dynamic_subpriority_ (0), - static_subpriority_ (0), - arrival_ (arrival), - deadline_ (deadline), - task_entry_ (task_entry), - original_dispatch_ (original_dispatch) -{ - // obtain, increment the next id - dispatch_id_ = next_id_++; -} - -Dispatch_Entry::Dispatch_Entry (const Dispatch_Entry &d) - : priority_ (d.priority_), - OS_priority_ (d.OS_priority_), - dynamic_subpriority_ (d.dynamic_subpriority_), - static_subpriority_ (d.static_subpriority_), - arrival_ (d.arrival_), - deadline_ (d.deadline_), - task_entry_ (d.task_entry_), - original_dispatch_ (d.original_dispatch_) -{ - // obtain, increment the next id - dispatch_id_ = next_id_++; -} - -int -Dispatch_Entry::operator < (const Dispatch_Entry &d) const -{ - // for positioning in the ordered dispatch multiset - - // lowest arrival time first - if (this->arrival_ != d.arrival_) - return this->arrival_ < d.arrival_ ? 1 : 0; - - // highest priority second - if (this->priority_ != d.priority_) - return this->priority_ > d.priority_ ? 1 : 0; - - // lowest laxity (highest dynamic sub-priority) third Just use low - // 32 bits of worst_case_execution_time. This will have to change - // when TimeBase.idl is finalized. - // - // NOTE: Leave the -= code intact as it's a workaround of a BCB4 - // internal compiler error. - Time this_laxity = deadline_; - this_laxity -= task_entry ().rt_info ()->worst_case_execution_time; - - Time that_laxity = d.deadline_; - that_laxity -= d.task_entry ().rt_info ()->worst_case_execution_time; - - if (this_laxity != that_laxity) - return (this_laxity < that_laxity) ? 1 : 0; - - // finally, by higher importance - return (task_entry ().rt_info ()->importance > - d.task_entry ().rt_info ()->importance) ? 1 : 0; -} - -// ctor - -Dispatch_Entry_Link::Dispatch_Entry_Link (Dispatch_Entry &d) - : dispatch_entry_ (d) -{ -} - -// copy ctor - -Dispatch_Entry_Link::Dispatch_Entry_Link (const Dispatch_Entry_Link &d) - : dispatch_entry_ (d.dispatch_entry_) -{ -} - -// ctor - -Dispatch_Proxy_Iterator::Dispatch_Proxy_Iterator - (ACE_Ordered_MultiSet <Dispatch_Entry_Link> &set, - u_long actual_frame_size, - u_long virtual_frame_size, - u_long number_of_calls, - u_long starting_sub_frame) - : number_of_calls_ (number_of_calls), - current_call_ (0), - actual_frame_size_ (actual_frame_size), - virtual_frame_size_ (virtual_frame_size), - current_frame_offset_ (actual_frame_size * starting_sub_frame), - iter_ (set) -{ - first (starting_sub_frame); -} - -// positions the iterator at the first entry of the passed sub-frame, -// returns 1 if it could position the iterator correctly, 0 if not, -// and -1 if an error occurred. - -int -Dispatch_Proxy_Iterator::first (u_int sub_frame) -{ - if (actual_frame_size_ * (sub_frame) >= virtual_frame_size_) - { - // can not position the virtual iterator - // in the given range: do nothing - return 0; - } - - // restart the call counter - current_call_ = 0; - - // use the given sub-frame offset if it's valid - current_frame_offset_ = actual_frame_size_ * sub_frame; - - // restart the iterator - return iter_.first (); -} - -// positions the iterator at the last entry of the total frame, -// returns 1 if it could position the iterator correctly, 0 if not, -// and -1 if an error occurred. - -int -Dispatch_Proxy_Iterator::last (void) -{ - // use the last call - current_call_ = number_of_calls_ - 1; - - // use the last sub-frame - current_frame_offset_ = virtual_frame_size_ - actual_frame_size_; - - // position the iterator at the last dispatch - return iter_.first (); -} - -// positions the iterator at the next entry of the total frame, -// returns 1 if it could position the iterator correctly, 0 if not, -// and -1 if an error occurred. - -int -Dispatch_Proxy_Iterator::advance (void) -{ - int result = 1; - - if (iter_.done ()) - result = 0; // cannot retreat if we're out of bounds - else if (current_call_ < number_of_calls_ - 1) - // if we're still in the same set of calls, increment the call counter - ++current_call_; - else - { - // roll over the call counter - current_call_ = 0; - - // advance the iterator in the current sub-frame - if (! iter_.advance ()) - { - // if we're not already in the last sub_frame - if (current_frame_offset_ + actual_frame_size_ < virtual_frame_size_) - { - // increment the sub-frame offset - current_frame_offset_ += actual_frame_size_; - - // restart the iterator at the front of the sub-frame - result = iter_.first (); - } - else - result = 0; // cannot advance if we're already at the end - } - } - - return result; -} - -// positions the iterator at the previous entry of the total frame, -// returns 1 if it could position the iterator correctly, 0 if not, -// and -1 if an error occurred. - -int -Dispatch_Proxy_Iterator::retreat (void) -{ - int result = 1; - - if (iter_.done ()) - result = 0; // cannot retreat if we're out of bounds - else if (current_call_ > 0) - // if we're still in the same set of calls, decrement the call counter - --current_call_; - else - { - // roll over the call counter - current_call_ = number_of_calls_ - 1; - - // back up the iterator in the current sub-frame - if (!iter_.retreat ()) - { - // if we're not already in the 0th sub_frame - if (current_frame_offset_ > 0) - { - // decrement the sub-frame offset - current_frame_offset_ -= actual_frame_size_; - - // restart the iterator at the tail of the sub-frame - result = iter_.last (); - } - else - result = 0; // cannot retreat if we're already at the start - } - } - - return result; -} - -// returns the adjusted arrival time of the virtual entry - -RtecScheduler::Time -Dispatch_Proxy_Iterator::arrival (void) const -{ - Dispatch_Entry_Link *link; - if (iter_.done () - || iter_.next(link) == 0 - || link == 0) - return 0; - - // Just use low 32 bits of arrival. This will have to change when - // TimeBase.idl is finalized. - return link->dispatch_entry ().arrival () + - RtecScheduler::Time (current_frame_offset_); -} - -// returns the adjusted deadline time of the virtual entry - -RtecScheduler::Time -Dispatch_Proxy_Iterator::deadline (void) const -{ - Dispatch_Entry_Link *link; - if (iter_.done () - || iter_.next(link) == 0 - || link == 0) - return 0; - - // Just use low 32 bits of deadline. This will have to change when - // TimeBase.idl is finalized. - return link->dispatch_entry ().deadline () + - RtecScheduler::Time (current_frame_offset_); -} - -// returns the scheduler priority of the virtual entry - -Dispatch_Proxy_Iterator::Preemption_Priority -Dispatch_Proxy_Iterator::priority (void) const -{ - Dispatch_Entry_Link *link; - - if (iter_.done () - || iter_.next(link) == 0 - || link == 0) - return 0; - - return link->dispatch_entry ().priority (); -} - -// returns the OS priority of the virtual entry - -Dispatch_Proxy_Iterator::OS_Priority -Dispatch_Proxy_Iterator::OS_priority (void) const -{ - Dispatch_Entry_Link *link; - if (iter_.done () - || iter_.next(link) == 0 - || link == 0) - return 0; - - return link->dispatch_entry ().OS_priority (); -} - -// time slice constructor - -TimeLine_Entry::TimeLine_Entry (Dispatch_Entry &dispatch_entry, - Time start, Time stop, - Time arrival, Time deadline, - TimeLine_Entry *next, - TimeLine_Entry *prev) - : dispatch_entry_ (dispatch_entry), - start_ (start), - stop_ (stop), - arrival_ (arrival), - deadline_ (deadline), - next_ (next), - prev_ (prev) -{ -} |