LoginSignup
0
0

More than 1 year has passed since last update.

boost 1.55.0のboost.utc_clockはsteadyの夢を見るか

Posted at

結論

GetSystemTimeAsFileTimeが使われてるっぽくて、これはmonotonic(steady)ではないぽい気がする。

utc_clock

boost.utc_clockはsteadyの夢を見るか

template< typename TimeTraitsT >
class basic_clock :
    public attribute
{
//略
protected:
    //! Attribute factory implementation
    struct BOOST_SYMBOL_VISIBLE impl :
        public attribute::impl
    {
        attribute_value get_value()
        {
            typedef attribute_value_impl< value_type > result_value;
            return attribute_value(new result_value(TimeTraitsT::get_clock()));
        }
    };

public:
    /*!
     * Default constructor
     */
    basic_clock() : attribute(new impl())
    {
    }
//略
};

//! Attribute that returns current UTC time
typedef basic_clock< utc_time_traits > utc_clock;

utc_time_traits,clock_source

boost\log\attributes\time_traits.hpp

//! Base class for time traits involving Boost.DateTime.
struct basic_time_traits
{
    //! Time type
    typedef posix_time::ptime time_type;

    //! Current time source
#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
    typedef posix_time::microsec_clock clock_source;
#else
    typedef posix_time::second_clock clock_source;
#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
};

//! Time traits that describes UTC time acquirement via Boost.DateTime facilities
struct utc_time_traits :
    public basic_time_traits
{
    /*!
     * \return Current time stamp
     */
    static time_type get_clock()
    {
        return clock_source::universal_time();
    }
};

BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK

boost\date_time\compiler_config.hpp

//Set up a configuration parameter for platforms that have 
//GetTimeOfDay
#if defined(BOOST_HAS_GETTIMEOFDAY) || defined(BOOST_HAS_FTIME)
#define BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
#endif

BOOST_HAS_FTIME

boost\config\platform\win32.hpp

#ifndef BOOST_DISABLE_WIN32
// WEK: Added
#define BOOST_HAS_FTIME
#define BOOST_WINDOWS 1

#endif

microsec_clock

boost\date_time\microsec_time_clock.hpp

  template<class time_type>
  class microsec_clock
  {
  private:
    //! Type for the function used to convert time_t to tm
    typedef std::tm* (*time_converter)(const std::time_t*, std::tm*);

  public:
    //! Returns the UTC time based on computer settings
    static time_type universal_time()
    {
      return create_time(&c_time::gmtime);
    }

  private:
    static time_type create_time(time_converter converter)
    {
#ifdef BOOST_HAS_GETTIMEOFDAY
      timeval tv;
      gettimeofday(&tv, 0); //gettimeofday does not support TZ adjust on Linux.
      std::time_t t = tv.tv_sec;
      boost::uint32_t sub_sec = tv.tv_usec;
#elif defined(BOOST_HAS_FTIME)
      winapi::file_time ft;
      winapi::get_system_time_as_file_time(ft);
      uint64_t micros = winapi::file_time_to_microseconds(ft); // it will not wrap, since ft is the current time
                                                               // and cannot be before 1970-Jan-01
      std::time_t t = static_cast<std::time_t>(micros / 1000000UL); // seconds since epoch
      // microseconds -- static casts supress warnings
      boost::uint32_t sub_sec = static_cast<boost::uint32_t>(micros % 1000000UL);
#else
#error Internal Boost.DateTime error: BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK is defined, however neither gettimeofday nor FILETIME support is detected.
#endif

      std::tm curr;
      std::tm* curr_ptr = converter(&t, &curr);
      date_type d(static_cast< typename date_type::year_type::value_type >(curr_ptr->tm_year + 1900),
                  static_cast< typename date_type::month_type::value_type >(curr_ptr->tm_mon + 1),
                  static_cast< typename date_type::day_type::value_type >(curr_ptr->tm_mday));

      //The following line will adjust the fractional second tick in terms
      //of the current time system.  For example, if the time system
      //doesn't support fractional seconds then res_adjust returns 0
      //and all the fractional seconds return 0.
      int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000);

      time_duration_type td(static_cast< typename time_duration_type::hour_type >(curr_ptr->tm_hour),
                            static_cast< typename time_duration_type::min_type >(curr_ptr->tm_min),
                            static_cast< typename time_duration_type::sec_type >(curr_ptr->tm_sec),
                            sub_sec * adjust);

      return time_type(d,td);
    }
  };

get_system_time_as_file_time

boost\date_time\filetime_functions.hpp

    inline void get_system_time_as_file_time(file_time& ft)
    {
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
        // Some runtime library implementations expect local times as the norm for ctime.
        file_time ft_utc;
        GetSystemTimeAsFileTime(&ft_utc);
        FileTimeToLocalFileTime(&ft_utc, &ft);
#elif defined(BOOST_HAS_GETSYSTEMTIMEASFILETIME)
        GetSystemTimeAsFileTime(&ft);
#else
        system_time st;
        GetSystemTime(&st);
        SystemTimeToFileTime(&st, &ft);
#endif
    }

GetSystemTimeAsFileTimeはmonotonic(steady)なのか・・・?

GetSystemTimeAsFileTime

Microsoft C/C++ 2003 - 2015 の変更履歴 | Microsoft Docs

steady_clock

steady_clock の <chrono> 実装が変更され、安定性と単調性のための C++ 標準の要件を満たすようになりました。 現在、steady_clockQueryPerformanceCounter() に基づき、high_resolution_clocksteady_clocktypedef です。 結果として、Visual Studio では現在、steady_clock::time_pointchrono::time_point<steady_clock>typedef です。ただし、他の実装では異なる場合があります。

c++ - VS11 is steady_clock, steady? - Stack Overflow

presumably VC++ 2012's std::steady_clock is not steady, as evidenced by multiple bug reports currently open on MS Connect regarding this very issue:

MSVC++2012の std::chrono の精度はどれくらい?

// MSVC++2012 : <chrono>
namespace std {
  namespace chrono {
    struct system_clock {
      ...
      static time_point now() __NOEXCEPT {
        return (time_point(duration(_Xtime_get_ticks())));
      }
      ...
    };
    class steady_clock : public system_clock { ... };
    typedef steady_clock monotonic_clock;
    typedef system_clock high_resolution_clock;
  }
}

つまるところだめそう

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0