static void
test_boundaries (void)
{
  ACE_Handle_Set handle_set;
  ACE_Unbounded_Set<ACE_HANDLE> set;
  ACE_HANDLE handle;

  // First test an empty set.

  for (ACE_Handle_Set_Iterator i1 (handle_set);
       (handle = i1 ()) != ACE_INVALID_HANDLE;
       )
    {
      ACE_ASSERT (0 ==
                  ACE_TEXT ("this shouldn't get called since ")
                  ACE_TEXT ("the set is empty!\n"));
    }

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("ACE_DEFAULT_SELECT_REACTOR_SIZE %d\n"),
              ACE_DEFAULT_SELECT_REACTOR_SIZE));

  // Insert the vector of <ACE_HANDLE>s into the set.

#if defined (ACE_WIN64)
  // The casts below are legit...
#  pragma warning(push)
#  pragma warning(disable : 4312)
#endif /* ACE_WIN64 */
  for (int i = 0;
       handle_vector[i] != ACE_INVALID_HANDLE;
       i++)
    {
      if (handle_vector[i] < (ACE_HANDLE) ACE_DEFAULT_SELECT_REACTOR_SIZE)
        {
          handle_set.set_bit (handle_vector[i]);
          set.insert (handle_vector[i]);
        }
    }
#if defined (ACE_WIN64)
#  pragma warning(pop)
#endif /* ACE_WIN64 */

  int count = 0;

  for (ACE_Handle_Set_Iterator i2 (handle_set);
       (handle = i2 ()) != ACE_INVALID_HANDLE;
       )
    {
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("obtained handle %d\n"),
                  handle));
      int done = set.remove (handle);
      ACE_ASSERT (done == 0);
      count++;
    }

  ACE_ASSERT (count == handle_set.num_set ());
}
Exemple #2
0
static void
test_boundaries (void)
{
  ACE_Handle_Set handle_set;
  ACE_Unbounded_Set<ACE_HANDLE> set;
  ACE_HANDLE handle;

  // First test an empty set.

  for (ACE_Handle_Set_Iterator i1 (handle_set);
       (handle = i1 ()) != ACE_INVALID_HANDLE;
       )
    {
#if defined (ACE_PSOS_DIAB)
      // Workaround for some compiler confusion with strings in
      // assertions.
      const int SET_IS_EMPTY_SO_SHOULD_NOT_SEE_THIS = 1;
      ACE_ASSERT (0 == SET_IS_EMPTY_SO_SHOULD_NOT_SEE_THIS);
#else /* ! defined (ACE_PSOS_DIAB) */
      ACE_ASSERT (0 ==
                  ACE_TEXT ("this shouldn't get called since ")
                  ACE_TEXT ("the set is empty!\n"));
#endif /* defined (ACE_PSOS_DIAB) */
    }

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("ACE_DEFAULT_SELECT_REACTOR_SIZE %d\n"),
              ACE_DEFAULT_SELECT_REACTOR_SIZE));

  // Insert the vector of <ACE_HANDLE>s into the set.

  for (int i = 0;
       handle_vector[i] != ACE_INVALID_HANDLE;
       i++)
    {
      if (handle_vector[i] < (ACE_HANDLE) ACE_DEFAULT_SELECT_REACTOR_SIZE)
        {
          handle_set.set_bit (handle_vector[i]);
          set.insert (handle_vector[i]);
        }
    }

  int count = 0;

  for (ACE_Handle_Set_Iterator i2 (handle_set);
       (handle = i2 ()) != ACE_INVALID_HANDLE;
       )
    {
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("obtained handle %d\n"),
                  handle));
      int done = set.remove (handle);
      ACE_ASSERT (done == 0);
      count++;
    }

  ACE_ASSERT (count == handle_set.num_set ());
}
Exemple #3
0
// Listing 1
// Listing 2 code/ch05
int SetExample::runUnboundedSet ()
{
  ACE_TRACE (ACE_TEXT ("SetExample::runUnboundedSet"));
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Using an unbounded set.\n")));
  ACE_Unbounded_Set<DataElement*> uset;
  for (int m = 0; m < 100; m++)
    {
      DataElement *elem;
      ACE_NEW_RETURN (elem, DataElement (m), -1);
      uset.insert (elem);
    }
  DataElement deBegin (0), deEnd (99);
  if (!uset.find (&deBegin) && !uset.find (&deEnd))
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Found the elements\n")));
    }

  // Iterate and destroy the elements in the set.
  ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Deleting the elements\n")));
  ACE_Unbounded_Set_Iterator<DataElement*> iter (uset);
  for (iter = uset.begin (); iter != uset.end (); iter++)
    {
      DataElement* elem = (*iter);
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d:"), elem->getData ()));
      delete elem;
    }

  return 0;
}
Exemple #4
0
int
run_main (int, ACE_TCHAR *[])
{
  int r;
  int retval = 0;
  unsigned k;
  MyNode node (1);

  ACE_START_TEST (ACE_TEXT ("Unbounded_Set_Test"));

  ACE_Unbounded_Set<MyNode> ubs;
  if (ubs.size () != 0)
    {
      ACE_ERROR ((LM_ERROR, "Error: ubs.size () != 0\n"));
      retval = -1;
    }
  if (!ubs.is_empty ())
    {
      ACE_ERROR ((LM_ERROR, "Error: !ubs.is_empty ()\n"));
      retval = -1;
    }

  // Insert a value. Immediately remove it.
  r = ubs.insert (node);
  if (r != 0)
    {
      ACE_ERROR ((LM_ERROR, "Error: r != 0\n"));
      retval = -1;
    }
  if (ubs.size () != 1)
    {
      ACE_ERROR ((LM_ERROR, "Error: ubs.size () != 1\n"));
      retval = -1;
    }
  r = ubs.remove (node);
  if (r != 0)
    {
      ACE_ERROR ((LM_ERROR, "Error: r != 0\n"));
      retval = -1;
    }
  if (ubs.size () != 0)
    {
      ACE_ERROR ((LM_ERROR, "Error: ubs.size () != 0\n"));
      retval = -1;
    }

  // Insert several different values.
  for (node.k = 1; node.k <= 5; node.k++)
    {
      r = ubs.insert (node);
      if (r != 0)
        {
          ACE_ERROR ((LM_ERROR, "Error: r != 0\n"));
          retval = -1;
        }
      if (ubs.size () != node.k)
        {
          ACE_ERROR ((LM_ERROR, "Error: ubs.size () != node.k\n"));
          retval = -1;
        }
    }

  // Test assigment of sets.
  // To do that, we also test some of the iterator methods.
  typedef ACE_Unbounded_Set<MyNode> MySet;
  MySet ubs2 = ubs;              // Test a typedef of a set.
  if (ubs2.size() != ubs.size())
    {
      ACE_ERROR ((LM_ERROR, "Error: ubs2.size() != ubs.size()\n"));
      retval = -1;
    }
  {
    MySet::ITERATOR it1 (ubs);
    MySet::iterator it2 (ubs2);
    for (k = 1; k <= 5; k++)
      {
        if (it1.done ())
          {
            ACE_ERROR ((LM_ERROR, "Error: it1.done ()\n"));
            retval = -1;
          }
        if (it2.done ())
          {
            ACE_ERROR ((LM_ERROR, "Error: it2.done ()\n"));
            retval = -1;
          }
        MyNode n1 = *it1;
        MyNode n2 = *it2;
        if (!(n1 == n2))
          {
            ACE_ERROR ((LM_ERROR, "Error: !(n1 == n2)\n"));
            retval = -1;
          }
        it1.advance ();
        it2.advance ();
      }
    if (!it1.done ())
      {
        ACE_ERROR ((LM_ERROR, "Error: !it1.done ()\n"));
        retval = -1;
      }
    if (!it2.done ())
      {
        ACE_ERROR ((LM_ERROR, "Error: !it2.done ()\n"));
        retval = -1;
      }
    // Verify that a set may be emptied while an iterator on the set is
    // in-scope but inactive:
    ubs.reset ();
    // Restore original set from ubs2
    ubs = ubs2;
  }

  // Selective deletion of elements and element retrieval.
  {
    MySet::iterator it (ubs2);
    int deleted = 0;
    while (! it.done ())
      {
        MyNode n = *it;
        it.advance ();  /* Being friendly here: Move the iterator on
                           so that element removal does not interfere
                           with the current iterator position.
                           The less friendly case, removal under the
                           current iterator position, is below.  */
        if (n.k % 2 == 1)
          {
            r = ubs2.remove (n);
            deleted++;
          }
      }
    if (ubs2.size () + deleted != ubs.size())
      {
        ACE_ERROR ((LM_ERROR, "Error: ubs2.size () + deleted != ubs.size()\n"));
        retval = -1;
      }

    MyNode node2 (2);
    if (ubs2.find (node2) != 0)
      {
        ACE_ERROR ((LM_ERROR, "Error: ubs2.find (node2) != 0\n"));
        retval = -1;
      }

    MyNode node3 (3);
    if (ubs2.find (node3) == 0)
      {
        ACE_ERROR ((LM_ERROR, "Error: ubs2.find (node3) == 0\n"));
        retval = -1;
      }

    ubs2.insert (node3);
  }

  size_t s = count_const_set (ubs);
  if (s != ubs.size ())
    {
      ACE_ERROR ((LM_ERROR, "Error: s != ubs.size ()\n"));
      retval = -1;
    }

  ACE_Unbounded_Set<MyNode> ubs_insert;
  MyNode node4 (4);
  if (ubs_insert.insert (node4) != 0)
    {
      ACE_ERROR ((LM_ERROR, "Error: insert node4 failed\n"));
      retval = -1;
    }
  if (ubs_insert.insert (node4) != 1)
    {
      ACE_ERROR ((LM_ERROR, "Error: insert node4 didn't return 1\n"));
      retval = -1;
    }

  // Test iterating through a set and deleting elements.
  {
    ACE_Unbounded_Set<MyNode*> ubs3;
    MyNode *n = 0;
    for (int i = 0; i < 10; ++i)
      {
        n = new MyNode (i);
        ubs3.insert (n);
      }
    MyNode **i_n = 0;
    ACE_Unbounded_Set_Iterator<MyNode*> ubs3_iter (ubs3.begin ());
    for (; ubs3_iter.next (i_n); ++ubs3_iter)
      delete *i_n;
  }
  ACE_END_TEST;
  return retval;
}
int
run_main (int, ACE_TCHAR *[])
{
  int r;
  unsigned k;
  MyNode node (1);

  ACE_START_TEST (ACE_TEXT ("Unbounded_Set_Test"));

  ACE_Unbounded_Set<MyNode> ubs;
  ACE_ASSERT (ubs.size () == 0);

  // Insert a value. Immediately remove it.
  r = ubs.insert (node);
  ACE_ASSERT (r == 0);
  ACE_ASSERT (ubs.size () == 1);
  r = ubs.remove (node);
  ACE_ASSERT (r == 0);
  ACE_ASSERT (ubs.size () == 0);

  // Insert several different values.
  for (node.k = 1; node.k <= 5; node.k++)
    {
      r = ubs.insert (node);
      ACE_ASSERT (r == 0);
      ACE_ASSERT (ubs.size () == node.k);
    }

  // Test assigment of sets.
  // To do that, we also test some of the iterator methods.
  typedef ACE_Unbounded_Set<MyNode> MySet;
  MySet ubs2 = ubs;              // Test a typedef of a set.
  ACE_ASSERT (ubs2.size() == ubs.size());
  {
    MySet::ITERATOR it1 (ubs);
    MySet::iterator it2 (ubs2);
    for (k = 1; k <= 5; k++)
      {
        ACE_ASSERT (! it1.done ());
        ACE_ASSERT (! it2.done ());
        MyNode n1 = *it1;
        MyNode n2 = *it2;
        ACE_ASSERT (n1 == n2);
        it1.advance ();
        it2.advance ();
      }
    ACE_ASSERT (it1.done ());
    ACE_ASSERT (it2.done ());
    // Verify that a set may be emptied while an iterator on the set is
    // in-scope but inactive:
    ubs.reset ();
    // Restore original set from ubs2
    ubs = ubs2;
  }

  // Selective deletion of elements and element retrieval.
  {
    MySet::iterator it (ubs2);
    int deleted = 0;
    while (! it.done ())
      {
        MyNode n = *it;
        it.advance ();  /* Being friendly here: Move the iterator on
                           so that element removal does not interfere
                           with the current iterator position.
                           The less friendly case, removal under the
                           current iterator position, is below.  */
        if (n.k % 2 == 1)
          {
            r = ubs2.remove (n);
            deleted++;
          }
      }
    ACE_ASSERT (ubs2.size () + deleted == ubs.size());

    MyNode node2 (2);
    ACE_ASSERT (ubs2.find (node2) == 0);

    MyNode node3 (3);
    ACE_ASSERT (ubs2.find (node3) != 0);

    ubs2.insert (node3);
  }

  size_t s = count_const_set (ubs);
  ACE_ASSERT (s == ubs.size ());

  // Test deletion under the cursor.
  // This is the regression test for Bugzilla bug 1460.
  {
    MySet::iterator end = ubs2.end ();
    for (MySet::iterator i = ubs2.begin (); i != end; i++)
      {
        r = ubs2.remove (*i);
        ACE_ASSERT (r == 0);
      }
    ACE_ASSERT (ubs2.size () == 0);
  }
  ACE_ASSERT (ubs2.is_empty ());

  ACE_END_TEST;
  return 0;
}
Exemple #6
0
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;
}
Exemple #7
0
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);
              ORBSVCS_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);
              ORBSVCS_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;
}