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

Johnny Willemsen jwillemsen at remedy.nl
Wed Feb 20 01:18:01 CST 2019


Hi,

>     When is the next ACE TAO release scheduled?

There is no schedule yet. Making a release takes all together a few
days, we mostly do it when it is necessary for a sponsor. In case your
project is interested in sponsoring this please contact me.

Best regards,

Johnny Willemsen
Remedy IT
http://www.remedy.nl
> 
>  
> 
> 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
> 


More information about the ace-users mailing list