📄 schedentry.cpp
字号:
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)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -