📄 schedentry.cpp
字号:
// SchedEntry.cpp,v 1.20 2003/11/04 05:21:32 dhinton Exp
// ============================================================================
//
// = LIBRARY
// sched
//
// = FILENAME
// SchedEntry.cpp
//
// = CREATION DATE
// 7 February 1998
//
// = AUTHOR
// Chris Gill
//
// ============================================================================
#include "SchedEntry.h"
#include "ace/SString.h"
#include "ace/OS_NS_stdio.h"
#if ! defined (__ACE_INLINE__)
#include "SchedEntry.i"
#endif /* __ACE_INLINE__ */
ACE_RCSID(Sched, SchedEntry, "SchedEntry.cpp,v 1.20 2003/11/04 05:21:32 dhinton Exp")
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 (RtecBase::TWO_WAY_CALL) < 0)
result = TWO_WAY_DISJUNCTION;
if (disjunctive_merge (RtecBase::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 (RtecBase::TWO_WAY_CALL) < 0)
result = TWO_WAY_CONJUNCTION;
if (conjunctive_merge (RtecBase::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 (RtecBase::TWO_WAY_CALL,
dispatch_entries,
unresolved_locals,
unresolved_remotes) < 0)
result = INTERNAL_ERROR;
if (conjunctive_merge (RtecBase::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 () == RtecBase::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 () == RtecBase::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 () == RtecBase::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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -