⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 schedentry.cpp

📁 这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用于网络游戏医学图像网关的高qos要求.更详细的内容可阅读相应的材料
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 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 + -