Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85779 - in trunk/boost: detail/win sync/detail sync/detail/mutexes sync/detail/semaphore
From: andrey.semashev_at_[hidden]
Date: 2013-09-18 17:25:36


Author: andysem
Date: 2013-09-18 17:25:36 EDT (Wed, 18 Sep 2013)
New Revision: 85779
URL: http://svn.boost.org/trac/boost/changeset/85779

Log:
Added GetSystemTimeAsFileTime definition when it is absent in WinAPI. Made constants as enum so that they can be used in switch/case statements. Added Boost.Sync time_units and mutex for Windows.

Added:
   trunk/boost/sync/detail/interlocked.hpp (contents, props changed)
   trunk/boost/sync/detail/mutexes/mutex_windows.hpp (contents, props changed)
Text files modified:
   trunk/boost/detail/win/synchronization.hpp | 26 +++-
   trunk/boost/detail/win/time.hpp | 20 ++
   trunk/boost/sync/detail/interlocked.hpp | 212 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/sync/detail/mutexes/mutex_windows.hpp | 181 ++++++++++++++++++++++++++++++++++
   trunk/boost/sync/detail/semaphore/semaphore_windows.hpp | 17 --
   trunk/boost/sync/detail/time_units.hpp | 120 ++++++++++++++++++++++
   6 files changed, 547 insertions(+), 29 deletions(-)

Modified: trunk/boost/detail/win/synchronization.hpp
==============================================================================
--- trunk/boost/detail/win/synchronization.hpp Wed Sep 18 15:53:48 2013 (r85778)
+++ trunk/boost/detail/win/synchronization.hpp 2013-09-18 17:25:36 EDT (Wed, 18 Sep 2013) (r85779)
@@ -47,11 +47,14 @@
     using ::WaitForSingleObject;
     using ::QueueUserAPC;
 
- static const DWORD_ infinite = INFINITE;
- static const DWORD_ wait_abandoned = WAIT_ABANDONED;
- static const DWORD_ wait_object_0 = WAIT_OBJECT_0;
- static const DWORD_ wait_timeout = WAIT_TIMEOUT;
- static const DWORD_ wait_failed = WAIT_FAILED;
+ enum
+ {
+ infinite = INFINITE,
+ wait_abandoned = WAIT_ABANDONED,
+ wait_object_0 = WAIT_OBJECT_0,
+ wait_timeout = WAIT_TIMEOUT,
+ wait_failed = WAIT_FAILED
+ };
 
 #else
 extern "C" {
@@ -123,11 +126,14 @@
     using ::SetEvent;
     using ::ResetEvent;
 
- static const DWORD_ infinite = (DWORD_)0xFFFFFFFF;
- static const DWORD_ wait_abandoned = 0x00000080L;
- static const DWORD_ wait_object_0 = 0x00000000L;
- static const DWORD_ wait_timeout = 0x00000102L;
- static const DWORD_ wait_failed = (DWORD_)0xFFFFFFFF;
+ enum
+ {
+ infinite = (DWORD_)0xFFFFFFFF,
+ wait_abandoned = 0x00000080L,
+ wait_object_0 = 0x00000000L,
+ wait_timeout = 0x00000102L,
+ wait_failed = (DWORD_)0xFFFFFFFF
+ };
 
 # endif
 }

Modified: trunk/boost/detail/win/time.hpp
==============================================================================
--- trunk/boost/detail/win/time.hpp Wed Sep 18 15:53:48 2013 (r85778)
+++ trunk/boost/detail/win/time.hpp 2013-09-18 17:25:36 EDT (Wed, 18 Sep 2013) (r85779)
@@ -23,7 +23,7 @@
     typedef SYSTEMTIME SYSTEMTIME_;
     typedef SYSTEMTIME* PSYSTEMTIME_;
 
- #ifndef UNDER_CE // Windows CE does not define GetSystemTimeAsFileTime
+ #ifdef BOOST_HAS_GETSYSTEMTIMEASFILETIME // Windows CE does not define GetSystemTimeAsFileTime
     using ::GetSystemTimeAsFileTime;
     #endif
     using ::FileTimeToLocalFileTime;
@@ -49,22 +49,32 @@
       WORD_ wMilliseconds;
     } SYSTEMTIME_, *PSYSTEMTIME_;
 
- #ifndef UNDER_CE // Windows CE does not define GetSystemTimeAsFileTime
+ #ifdef BOOST_HAS_GETSYSTEMTIMEASFILETIME // Windows CE does not define GetSystemTimeAsFileTime
     __declspec(dllimport) void WINAPI
         GetSystemTimeAsFileTime(FILETIME_* lpFileTime);
     #endif
     __declspec(dllimport) int WINAPI
- FileTimeToLocalFileTime(const FILETIME_* lpFileTime,
+ FileTimeToLocalFileTime(const FILETIME_* lpFileTime,
                 FILETIME_* lpLocalFileTime);
     __declspec(dllimport) void WINAPI
         GetSystemTime(SYSTEMTIME_* lpSystemTime);
     __declspec(dllimport) int WINAPI
- SystemTimeToFileTime(const SYSTEMTIME_* lpSystemTime,
+ SystemTimeToFileTime(const SYSTEMTIME_* lpSystemTime,
                 FILETIME_* lpFileTime);
- __declspec(dllimport) unsigned long __stdcall
+ __declspec(dllimport) DWORD_ WINAPI
         GetTickCount();
 }
 #endif
+
+#ifndef BOOST_HAS_GETSYSTEMTIMEASFILETIME
+inline void WINAPI GetSystemTimeAsFileTime(FILETIME_* lpFileTime)
+{
+ SYSTEMTIME_ st;
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, lpFileTime);
+}
+#endif
+
 }
 }
 }

Added: trunk/boost/sync/detail/interlocked.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/detail/interlocked.hpp 2013-09-18 17:25:36 EDT (Wed, 18 Sep 2013) (r85779)
@@ -0,0 +1,212 @@
+/*
+ * 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)
+ *
+ * (C) Copyright 2005-8 Anthony Williams
+ * (C) Copyright 2012-2013 Vicente J. Botet Escriba
+ * (C) Copyright 2013 Andrey Semashev
+ */
+/*!
+ * \file interlocked.hpp
+ *
+ * \brief This header is the Boost.Sync library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/sync/doc/html/index.html.
+ */
+
+#ifndef BOOST_SYNC_DETAIL_INTERLOCKED_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_INTERLOCKED_HPP_INCLUDED_
+
+#include <boost/atomic/detail/interlocked.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+namespace detail {
+
+namespace windows {
+
+#if defined(BOOST_MSVC) && (_MSC_VER >= 1400) && !defined(UNDER_CE)
+
+#if _MSC_VER == 1400
+extern "C" unsigned char _interlockedbittestandset(long *a, long b);
+extern "C" unsigned char _interlockedbittestandreset(long *a, long b);
+#else
+extern "C" unsigned char _interlockedbittestandset(volatile long *a, long b);
+extern "C" unsigned char _interlockedbittestandreset(volatile long *a, long b);
+#endif
+
+#pragma intrinsic(_interlockedbittestandset)
+#pragma intrinsic(_interlockedbittestandreset)
+
+BOOST_FORCEINLINE bool interlocked_bit_test_and_set(long* x, long bit) BOOST_NOEXCEPT
+{
+ return _interlockedbittestandset(x, bit) != 0;
+}
+
+BOOST_FORCEINLINE bool interlocked_bit_test_and_reset(long* x, long bit) BOOST_NOEXCEPT
+{
+ return _interlockedbittestandreset(x, bit) != 0;
+}
+
+#define BOOST_SYNC_DETAIL_BTS_DEFINED
+
+#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
+
+BOOST_FORCEINLINE bool interlocked_bit_test_and_set(long* x, long bit) BOOST_NOEXCEPT
+{
+#ifndef BOOST_INTEL_CXX_VERSION
+ __asm
+ {
+ mov eax,bit;
+ mov edx,x;
+ lock bts [edx], eax;
+ setc al;
+ };
+#else
+ bool ret;
+ __asm
+ {
+ mov eax,bit
+ mov edx,x
+ lock bts [edx], eax
+ setc ret
+ };
+ return ret;
+#endif
+}
+
+BOOST_FORCEINLINE bool interlocked_bit_test_and_reset(long* x, long bit) BOOST_NOEXCEPT
+{
+#ifndef BOOST_INTEL_CXX_VERSION
+ __asm
+ {
+ mov eax,bit;
+ mov edx,x;
+ lock btr [edx],eax;
+ setc al;
+ };
+#else
+ bool ret;
+ __asm
+ {
+ mov eax,bit
+ mov edx,x
+ lock btr [edx],eax
+ setc ret
+ };
+ return ret;
+#endif
+}
+
+#define BOOST_SYNC_DETAIL_BTS_DEFINED
+#endif
+
+#ifndef BOOST_SYNC_DETAIL_BTS_DEFINED
+
+BOOST_FORCEINLINE bool interlocked_bit_test_and_set(long* x, long bit) BOOST_NOEXCEPT
+{
+ long const value = 1 << bit;
+ long old = *x;
+ while (true)
+ {
+ long const current = BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(x, old | value, old);
+ if (current == old)
+ break;
+ old = current;
+ }
+ return (old & value) != 0;
+}
+
+BOOST_FORCEINLINE bool interlocked_bit_test_and_reset(long* x, long bit) BOOST_NOEXCEPT
+{
+ long const value = 1 << bit;
+ long old = *x;
+ while (true)
+ {
+ long const current = BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(x, old & ~value, old);
+ if (current == old)
+ break;
+ old = current;
+ }
+ return (old & value) != 0;
+}
+
+#endif
+
+#undef BOOST_SYNC_DETAIL_BTS_DEFINED
+
+#if defined(__INTEL_COMPILER)
+#define BOOST_SYNC_COMPILER_BARRIER __memory_barrier();
+#elif defined(_MSC_VER) && _MSC_VER >= 1310 && !defined(_WIN32_WCE)
+extern "C" void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+#define BOOST_SYNC_COMPILER_BARRIER() _ReadWriteBarrier()
+#endif
+
+#ifdef BOOST_SYNC_COMPILER_BARRIER
+
+BOOST_FORCEINLINE long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
+{
+ long const res = *x;
+ BOOST_SYNC_COMPILER_BARRIER;
+ return res;
+}
+BOOST_FORCEINLINE void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
+{
+ void* const res = *x;
+ BOOST_SYNC_COMPILER_BARRIER;
+ return res;
+}
+
+BOOST_FORCEINLINE void interlocked_write_release(long volatile* x, long value) BOOST_NOEXCEPT
+{
+ BOOST_SYNC_COMPILER_BARRIER;
+ *x = value;
+}
+BOOST_FORCEINLINE void interlocked_write_release(void* volatile* x, void* value) BOOST_NOEXCEPT
+{
+ BOOST_SYNC_COMPILER_BARRIER;
+ *x = value;
+}
+
+#else
+
+BOOST_FORCEINLINE long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
+{
+ return BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(x, 0);
+}
+BOOST_FORCEINLINE void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
+{
+ return BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(x, 0);
+}
+
+BOOST_FORCEINLINE void interlocked_write_release(long volatile* x, long value) BOOST_NOEXCEPT
+{
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE(x, value);
+}
+BOOST_FORCEINLINE void interlocked_write_release(void* volatile* x, void* value) BOOST_NOEXCEPT
+{
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(x, value);
+}
+
+#endif
+
+} // namespace windows
+
+} // namespace detail
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_INTERLOCKED_HPP_INCLUDED_

Added: trunk/boost/sync/detail/mutexes/mutex_windows.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/detail/mutexes/mutex_windows.hpp 2013-09-18 17:25:36 EDT (Wed, 18 Sep 2013) (r85779)
@@ -0,0 +1,181 @@
+/*
+ * 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)
+ *
+ * (C) Copyright 2007-2008 Anthony Williams
+ * (C) Copyright 2012-2013 Vicente J. Botet Escriba
+ * (C) Copyright 2013 Andrey Semashev
+ */
+/*!
+ * \file detail/mutexes/mutex_windows.hpp
+ *
+ * \brief This header is the Boost.Sync library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/sync/doc/html/index.html.
+ */
+
+#ifndef BOOST_SYNC_DETAIL_MUTEXES_MUTEX_WINDOWS_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_MUTEXES_MUTEX_WINDOWS_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/detail/win/handles.hpp>
+#include <boost/detail/win/synchronization.hpp>
+#include <boost/sync/exceptions/lock_error.hpp>
+#include <boost/sync/exceptions/resource_error.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/detail/interlocked.hpp>
+
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
+
+class mutex
+{
+private:
+ enum
+ {
+ lock_flag_bit = 31u,
+ event_set_flag_bit = 30u,
+ lock_flag_value = 1u << lock_flag_bit,
+ event_set_flag_value = 1u << event_set_flag_bit
+ };
+
+private:
+ long m_active_count;
+ boost::detail::win32::HANDLE_ m_event;
+
+public:
+ BOOST_CONSTEXPR mutex() BOOST_NOEXCEPT : m_event(NULL), m_active_count(0)
+ {
+ }
+
+ ~mutex()
+ {
+ if (m_event)
+ BOOST_VERIFY(boost::detail::win32::CloseHandle(m_event) != 0);
+ }
+
+ void lock()
+ {
+ if (try_lock())
+ return;
+
+ long old_count = m_active_count;
+ mark_waiting_and_try_lock(old_count);
+
+ if (old_count & lock_flag_value)
+ {
+ bool lock_acquired = false;
+ boost::detail::win32::HANDLE_ const sem = get_event();
+
+ do
+ {
+ const boost::detail::win32::DWORD_ retval = boost::detail::win32::WaitForSingleObject(sem, boost::detail::win32::infinite);
+ BOOST_ASSERT(0 == retval || boost::detail::win32::wait_abandoned == retval);
+ clear_waiting_and_try_lock(old_count);
+ lock_acquired = (old_count & lock_flag_value) == 0;
+ }
+ while (!lock_acquired);
+ }
+ }
+
+ void unlock() BOOST_NOEXCEPT
+ {
+ long const offset = lock_flag_value;
+ long const old_count = BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&m_active_count, lock_flag_value);
+ if ((old_count & event_set_flag_value) == 0 && (old_count > offset))
+ {
+ if (!sync::detail::windows::interlocked_bit_test_and_set(&m_active_count, event_set_flag_bit))
+ {
+ boost::detail::win32::SetEvent(get_event());
+ }
+ }
+ }
+
+ bool try_lock() BOOST_NOEXCEPT
+ {
+ return !sync::detail::windows::interlocked_bit_test_and_set(&m_active_count, lock_flag_bit);
+ }
+
+ BOOST_DELETED_FUNCTION(mutex(mutex const&))
+ BOOST_DELETED_FUNCTION(mutex& operator= (mutex const&))
+
+private:
+ boost::detail::win32::HANDLE_ get_event()
+ {
+ boost::detail::win32::HANDLE_ event = sync::detail::windows::interlocked_read_acquire(&m_event);
+
+ if (!event)
+ {
+ event = boost::detail::win32::CreateEventA(NULL, false, false, NULL);
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4311)
+#pragma warning(disable:4312)
+#endif
+ boost::detail::win32::HANDLE_ const old_event = BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&m_event, event, NULL);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+ if (old_event != NULL)
+ {
+ boost::detail::win32::CloseHandle(event);
+ return old_event;
+ }
+ }
+
+ return event;
+ }
+
+ void mark_waiting_and_try_lock(long& old_count)
+ {
+ while (true)
+ {
+ bool const was_locked = (old_count & lock_flag_value) ? true : false;
+ long const new_count = was_locked ? (old_count + 1) : (old_count | lock_flag_value);
+ long const current = BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&m_active_count, new_count, old_count);
+ if (current == old_count)
+ {
+ if (was_locked)
+ old_count = new_count;
+ break;
+ }
+ old_count = current;
+ }
+ }
+
+ void clear_waiting_and_try_lock(long& old_count)
+ {
+ old_count &= ~lock_flag_value;
+ old_count |= event_set_flag_value;
+ while (true)
+ {
+ long const new_count = ((old_count & lock_flag_value) ? old_count : ((old_count - 1) | lock_flag_value)) & ~static_cast< long >(event_set_flag_value);
+ long const current = BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&m_active_count, new_count, old_count);
+ if (current == old_count)
+ break;
+
+ old_count = current;
+ }
+ }
+};
+
+} // namespace posix
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_MUTEXES_MUTEX_POSIX_HPP_INCLUDED_

Modified: trunk/boost/sync/detail/semaphore/semaphore_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/semaphore/semaphore_windows.hpp Wed Sep 18 15:53:48 2013 (r85778)
+++ trunk/boost/sync/detail/semaphore/semaphore_windows.hpp 2013-09-18 17:25:36 EDT (Wed, 18 Sep 2013) (r85779)
@@ -39,13 +39,6 @@
     typedef boost::detail::win32::LONG_ LONG_;
     typedef boost::detail::win32::BOOL_ BOOL_;
 
- static const DWORD_ infinite = (DWORD_)0xFFFFFFFF;
- static const DWORD_ wait_abandoned = 0x00000080L;
- static const DWORD_ wait_object_0 = 0x00000000L;
- static const DWORD_ wait_timeout = 0x00000102L;
- static const DWORD_ wait_failed = (DWORD_)0xFFFFFFFF;
-
-
 public:
     explicit semaphore(unsigned int i = 0)
     {
@@ -77,10 +70,10 @@
     {
         switch (boost::detail::win32::WaitForSingleObject(m_sem, boost::detail::win32::infinite))
         {
- case wait_object_0:
+ case boost::detail::win32::wait_object_0:
             return true;
 
- case wait_failed:
+ case boost::detail::win32::wait_failed:
             {
                 const DWORD_ err = boost::detail::win32::GetLastError();
                 BOOST_THROW_EXCEPTION(resource_error(err, "boost::sync::semaphore::wait failed in WaitForSingleObject"));
@@ -119,13 +112,13 @@
     {
         switch (boost::detail::win32::WaitForSingleObject(m_sem, milliseconds))
         {
- case wait_object_0:
+ case boost::detail::win32::wait_object_0:
             return true;
 
- case wait_timeout:
+ case boost::detail::win32::wait_timeout:
             return false;
 
- case wait_failed:
+ case boost::detail::win32::wait_failed:
             {
                 const DWORD_ err = boost::detail::win32::GetLastError();
                 BOOST_THROW_EXCEPTION(resource_error(err, "boost::sync::semaphore::do_try_wait_for failed in WaitForSingleObject"));

Modified: trunk/boost/sync/detail/time_units.hpp
==============================================================================
--- trunk/boost/sync/detail/time_units.hpp Wed Sep 18 15:53:48 2013 (r85778)
+++ trunk/boost/sync/detail/time_units.hpp 2013-09-18 17:25:36 EDT (Wed, 18 Sep 2013) (r85779)
@@ -17,6 +17,11 @@
 #include <time.h>
 #include <boost/cstdint.hpp>
 #include <boost/sync/detail/config.hpp>
+
+#if defined(BOOST_SYNC_DETAIL_PLATFORM_WINAPI)
+#include <boost/detail/win/time.hpp>
+#endif
+
 #include <boost/sync/detail/header.hpp>
 
 #ifdef BOOST_HAS_PRAGMA_ONCE
@@ -86,7 +91,7 @@
 
 public:
     time_point() : m_value() {}
- explicit time_point(time_t t, unsigned long subsecond = 0)
+ explicit time_point(time_t t, unsigned int subsecond = 0)
     {
         m_value.tv_sec = t;
         m_value.tv_nsec = subsecond;
@@ -116,6 +121,8 @@
         }
         m_value.tv_nsec = tv_nsec;
         m_value.tv_sec += nsec / duration::subsecond_fraction;
+
+ return *this;
     }
     time_point& operator-= (duration const& dur)
     {
@@ -143,7 +150,116 @@
 
 #elif defined(BOOST_SYNC_DETAIL_PLATFORM_WINAPI)
 
-// TODO
+class duration
+{
+public:
+ typedef int64_t native_type;
+ // The native duration is in milliseconds
+ static BOOST_CONSTEXPR_OR_CONST uint64_t subsecond_fraction = 1000u;
+
+private:
+ native_type m_value;
+
+public:
+ duration() : m_value(0) {}
+ explicit duration(native_type value) : m_value(value) {}
+
+ native_type get() const { return m_value; }
+
+ duration& operator+= (duration const& that)
+ {
+ m_value += that.m_value;
+ return *this;
+ }
+ duration& operator-= (duration const& that)
+ {
+ m_value -= that.m_value;
+ return *this;
+ }
+ duration operator- () const
+ {
+ return duration(-m_value);
+ }
+
+ friend duration operator+ (duration left, duration const& right)
+ {
+ left += right;
+ return left;
+ }
+ friend duration operator- (duration left, duration const& right)
+ {
+ left -= right;
+ return left;
+ }
+};
+
+class time_point
+{
+public:
+ typedef uint64_t native_type;
+ // The native subsecond precision is milliseconds
+ static BOOST_CONSTEXPR_OR_CONST uint64_t subsecond_fraction = duration::subsecond_fraction;
+
+private:
+ native_type m_value;
+
+public:
+ time_point() : m_value(0) {}
+ explicit time_point(time_t t, unsigned int subsecond = 0) : m_value(static_cast< uint64_t >(t) * subsecond_fraction + subsecond)
+ {
+ }
+
+ native_type const& get() const { return m_value; }
+
+ static time_point now()
+ {
+ union
+ {
+ uint64_t as_uint64;
+ boost::detail::win32::FILETIME_ as_filetime;
+ }
+ caster;
+ boost::detail::win32::GetSystemTimeAsFileTime(&caster.as_filetime);
+
+ // Compensate the difference between 1970-Jan-01 & 1601-Jan-01
+ // in 100-nanosecond intervals
+ caster.as_uint64 -= 116444736000000000ull; // (27111902 << 32) + 3577643008
+
+ // Convert to milliseconds
+ caster.as_uint64 /= 10000u;
+
+ time_point res;
+ res.m_value = caster.as_uint64;
+ return res;
+ }
+
+ time_point& operator+= (duration const& dur)
+ {
+ m_value += dur.get();
+ return *this;
+ }
+ time_point& operator-= (duration const& dur)
+ {
+ m_value -= dur.get();
+ return *this;
+ }
+
+ friend time_point operator+ (time_point left, duration const& right)
+ {
+ left += right;
+ return left;
+ }
+ friend time_point operator- (time_point left, duration const& right)
+ {
+ left -= right;
+ return left;
+ }
+
+ friend duration operator- (time_point const& left, time_point const& right)
+ {
+ return duration(static_cast< duration::native_type >(left.m_value - right.m_value));
+ }
+};
 
 #endif
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk