/* * Copyright Andrey Semashev 2012. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */ #if (defined(_MSC_VER) && _MSC_VER > 1000) #pragma once #endif // _MSC_VER > 1000 #ifndef BOOST_THREAD_PTHREAD_TIME_UNITS_HPP_INCLUDED_ #define BOOST_THREAD_PTHREAD_TIME_UNITS_HPP_INCLUDED_ #include #include #include namespace boost { namespace detail { class thread_duration { public: typedef int64_t native_type; // The native duration is in nanoseconds static const uint64_t subsecond_fraction = 1000000000u; private: native_type m_value; public: thread_duration() : m_value(0) {} explicit thread_duration(native_type value) : m_value(value) {} native_type get() const { return m_value; } thread_duration& operator+= (thread_duration const& that) { m_value += that.m_value; return *this; } thread_duration& operator-= (thread_duration const& that) { m_value -= that.m_value; return *this; } thread_duration operator- () const { return thread_duration(-m_value); } friend thread_duration operator+ (thread_duration left, thread_duration const& right) { left += right; return left; } friend thread_duration operator- (thread_duration left, thread_duration const& right) { left -= right; return left; } }; class thread_time { public: typedef struct ::timespec native_type; // The native subsecond precision is nanoseconds static const uint64_t subsecond_fraction = thread_duration::subsecond_fraction; private: native_type m_value; public: thread_time() : m_value() {} explicit thread_time(time_t t, unsigned long subsecond = 0) { m_value.tv_sec = t; m_value.tv_nsec = subsecond; } native_type const& get() const { return m_value; } static thread_time now() { #if defined(BOOST_HAS_CLOCK_GETTIME) thread_time t; ::clock_gettime(CLOCK_REALTIME, &t.m_value); return t; #else return thread_time(::time(0)); #endif } thread_time& operator+= (thread_duration const& dur) { int64_t nsec = static_cast< int64_t >(m_value.tv_nsec) + dur.get(); int64_t tv_nsec = nsec % thread_duration::subsecond_fraction; if (tv_nsec < 0) { tv_nsec += subsecond_fraction; --m_value.tv_sec; } m_value.tv_nsec = tv_nsec; m_value.tv_sec += nsec / thread_duration::subsecond_fraction; } thread_time& operator-= (thread_duration const& dur) { return operator+= (-dur); } friend thread_time operator+ (thread_time left, thread_duration const& right) { left += right; return left; } friend thread_time operator- (thread_time left, thread_duration const& right) { left -= right; return left; } friend thread_duration operator- (thread_time const& left, thread_time const& right) { int64_t seconds = static_cast< int64_t >(left.m_value.tv_sec) - static_cast< int64_t >(right.m_value.tv_sec); int64_t nseconds = static_cast< int64_t >(left.m_value.tv_nsec) - static_cast< int64_t >(right.m_value.tv_nsec); return thread_duration(seconds * thread_duration::subsecond_fraction + nseconds); } }; } // namespace detail } // namespace boost #endif // BOOST_THREAD_PTHREAD_TIME_UNITS_HPP_INCLUDED_