[ace-users] EXT :Re: ACE Library Bug: ACE_Thread_Timer_Queue_Adapter has a Time Policy Issue

Wanner, Charles W [US] (AS) charles.wanner at ngc.com
Tue Feb 19 12:16:03 CST 2019


Hello,

    When is the next ACE TAO release scheduled?

Thank You,
Chuck W.

From: Johnny Willemsen [mailto:jwillemsen at remedy.nl]
Sent: Tuesday, February 19, 2019 4:47 AM
To: Wanner, Charles W [US] (AS) <charles.wanner at ngc.com>; ace-users at list.isis.vanderbilt.edu
Subject: EXT :Re: [ace-users] ACE Library Bug: ACE_Thread_Timer_Queue_Adapter has a Time Policy Issue


Hi,

Thanks for using the PRF form. We discussed your issue this morning within our Remedy IT support team. During the discussion we identified a much easier and smaller solution which we implemented and tested. See https://github.com/DOCGroup/ACE_TAO/pull/837 for the pull request we prepared and merged to ACE/TAO master, this change will be part of the next ACE release.

Johnny Willemsen

Remedy IT

http://www.remedy.nl
On 2/19/19 3:33 AM, Wanner, Charles W [US] (AS) wrote:
Version: ACE+TAO 6.4.5

HOST: CentOS Linux release 7.6.1810 (Core)

Config.h Contents:
#define ACE_ENABLE_SWAP_ON_WRITE
#define ACE_LACKS_CDR_ALIGNMENT
#define ACE_HAS_CLOCK_GETTIME_MONOTONIC
#define ACE_HAS_IPV6
#define ACE_USES_IPV4_IPV6_MIGRATION
#include "ace/config-linux.h"

AREA/CLASS/EXAMPLE AFFECTED: class ACE_Thread_Timer_Queue_Adapter (file: Timer_Queue_Adapter.[h,inl,cpp])

DOES THE PROBLEM AFFECT: Execution

SYNOPSIS:
   The thread created by the class ACE_Thread_Timer_Queue_Adapter will not pend and just continue to consume the CPU.
The problem occurs when the TQ Type is not using the ACE_Default_Time_Policy.

DESCRIPTION:

Declaration of the ACE_Thread_Timer_Queue_Adapter:

template <class TQ, class TYPE = ACE_Event_Handler*>
class ACE_Thread_Timer_Queue_Adapter : public ACE_Task_Base

The issue is when class TQ's Time Policy is not the ACE_Default_Time_Policy.  The root of the problem is class's
condition_ is always expecting a time value based on the default time policy (Wall Clock Time).  In the
ACE_Thread_Timer_Queue_Adapter::svc method the absolute time to wait for a scheduled timer will be based on TQ's
Time Policy (line 279), but condition_ is expecting an absolute time to be based on the default time policy (Wall Clock Time)
(line 282).


>From the ACE_Thread_Timer_Queue_Adapter::svc method, lines 268-283

          // Compute the remaining time, being careful not to sleep
          // for "negative" amounts of time.
          ACE_Time_Value const tv_curr =
            this->timer_queue_->gettimeofday ();
          ACE_Time_Value const tv_earl =
            this->timer_queue_->earliest_time ();

          if (tv_earl > tv_curr)
            {
              // The earliest time on the Timer_Queue lies in future;
              // convert the tv to an absolute time.
              ACE_Time_Value const tv = this->timer_queue_->gettimeofday () + (tv_earl - tv_curr);   // tv based on the Time from the TQ's Time Policy
              // ACELIB_DEBUG ((LM_DEBUG,  ACE_TEXT ("waiting until %u.%3.3u secs\n"),
              // tv.sec(), tv.msec()));
              this->condition_.wait (&tv);   // condition_ is expecting an absolute time to always be based on the default time policy (Wall Clock Time)
            }

REPEAT BY:

1) Declare the ACE_Thread_Timer_Queue_Adapter with the following parameters:

    class MyTimerInterface : public ACE_Task<ACE_MT_SYNCH, ACE_Monotonic_Time_Policy>

    ......
    /**
     * \brief Timer Interface Timer Heap Type
     */
    typedef ACE_Timer_Heap_T<ACE_Event_Handler *,
                             ACE_Event_Handler_Handle_Timeout_Upcall,
                             ACE_SYNCH_RECURSIVE_MUTEX,
                             ACE_Monotonic_Time_Policy> MyTimerHeapTyp;
    /**
     * \brief  My Interface Timer Queue Thread Type
     */
    typedef ACE_Thread_Timer_Queue_Adapter<MyTimerHeapTyp> MyTimerQThreadTyp;

    MyTimerQThreadTyp   myTimerT;

    .....

    };

 2) Schedule a periodic timer with myTimerT
 3) Monitor the CPU utilization of the process or process threads with top.
 4) top should show the thread created by myTimerT member constantly running and consuming the CPU.
 5) I use the following API call to set the thread's name to know which of my threads are displayed in top.
    /*
    ** Set the Linux Process/Thread Name
    */
    prctl(PR_SET_NAME, "MyTimerT");

    Just add the line to the MyTimerInterface::handle_timeout method of the ACE_Event_Hander object passed to the schedule method.

    this->myTimerT.schedule(this, .....)

    When you use the "top -H -p <Process's PID>", you should see "MyTimerT" under top's "COMMAND" column.

SAMPLE FIX/WORKAROUND:

  I think the based solution would be to add a ACE Condition Attributes data member similar to class Message_Queue_T

  I got this declaration from Message_Queue_T.h, lines 611-615.  Add the following lines to the private section of
  ACE_Thread_Timer_Queue_Adapter class:
    /// Attributes to initialize conditions with.
  /* We only need this because some crappy compilers can't
     properly handle initializing the conditions with
     temporary objects. */
  ACE_Condition_Attributes_T<TIME_POLICY> cond_attr_;

  Update line 162 in Timer_Queue_Adapter.cpp:
     condition_ (mutex_),
  Change To:
     condition_ (mutex_, cond_attr_),

  The issue with the fix is the TIME_POLICY Type.  The current declaration has TIME_POLICY in the
  TQ Type, so it is not currently available in the ACE_Thread_Timer_Queue_Adapter.   My knowledge on
  C++ Templates is not great.  So not positive if there is a way for the ACE_Thread_Timer_Queue_Adapter
  class to have access to the TIME_POLICY from the TQ type to declare a data member.  If it is not possible,
  then TIME_POLICY type would need to be added to the ACE_Thread_Timer_Queue_Adapter declaration.

  Currently:
   template <class TQ, class TYPE = ACE_Event_Handler*>
   class ACE_Thread_Timer_Queue_Adapter : public ACE_Task_Base

  My Change:
   template <class TQ, class TYPE = ACE_Event_Handler*, typename TIME_POLICY = ACE_Default_Time_Policy>
   class ACE_Thread_Timer_Queue_Adapter : public ACE_Task_Base

  Adding the TIME_POLICY at the end and defaulting the value to ACE_Default_Time_Policy should not cause compilation errors
  with existing code.

  My one concern is the TQ's TIME_POLICY could be out of synch with ACE_Thread_Timer_Queue_Adapter's TIME_POLICY.  Hopefully
  there is a way to do a validation check at compile time.  As of now, I do not know how to do a validation check if the two
  TIME_POLICY types were not the same.

  Each of the method's declaration had to be updated in the Timer_Queue_Adapter.inl and Timer_Queue_Adapter.cpp.

  I have implemented, compiled, and tested to ACE_Thread_Timer_Queue_Adapter class.  The problem with the CPU processing has
  gone away when using the ACE_Monotonic_Time_Policy.

  The new code is the following:

    class MyTimerInterface : public ACE_Task<ACE_MT_SYNCH, ACE_Monotonic_Time_Policy>

    ......
    /**
     * \brief Timer Interface Timer Heap Type
     */
    typedef ACE_Timer_Heap_T<ACE_Event_Handler *,
                             ACE_Event_Handler_Handle_Timeout_Upcall,
                             ACE_SYNCH_RECURSIVE_MUTEX,
                             ACE_Monotonic_Time_Policy> MyTimerHeapTyp;
    /**
     * \brief  My Interface Timer Queue Thread Type
     */
    typedef ACE_Thread_Timer_Queue_Adapter<MyTimerHeapTyp,
                                           ACE_Event_Handler *,
                                           ACE_Monotonic_Time_Policy> MyTimerQThreadTyp;

    MyTimerQThreadTyp   myTimerT;

    .....

    };

Chuck Wanner






_______________________________________________

ace-users mailing list

ace-users at list.isis.vanderbilt.edu<mailto:ace-users at list.isis.vanderbilt.edu>

http://list.isis.vanderbilt.edu/cgi-bin/mailman/listinfo/ace-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.isis.vanderbilt.edu/pipermail/ace-users/attachments/20190219/839039f2/attachment-0001.html>


More information about the ace-users mailing list