From 04c53415fd0adc1921d419c54a1e5ec4b19917ea Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Sat, 5 Jul 2014 16:38:17 +0100 Subject: [PATCH 1/3] Extracted the original GetTicksCount64 de-cruft patch and rebased on boostorg/thread:develop. --- build/Jamfile.v2 | 1 - include/boost/thread/win32/gettickcount64.hpp | 29 ----- include/boost/thread/win32/thread_data.hpp | 7 +- .../boost/thread/win32/thread_primitives.hpp | 113 +++++++++++++----- src/win32/gettickcount64.cpp | 48 -------- src/win32/thread.cpp | 2 +- 6 files changed, 86 insertions(+), 114 deletions(-) delete mode 100644 include/boost/thread/win32/gettickcount64.hpp delete mode 100644 src/win32/gettickcount64.cpp diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index cd069e82..628b71b6 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -284,7 +284,6 @@ alias thread_sources win32/thread.cpp win32/tss_dll.cpp win32/tss_pe.cpp - win32/gettickcount64.cpp future.cpp : ## requirements ## win32 diff --git a/include/boost/thread/win32/gettickcount64.hpp b/include/boost/thread/win32/gettickcount64.hpp deleted file mode 100644 index 06abbd23..00000000 --- a/include/boost/thread/win32/gettickcount64.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef BOOST_WIN32_GET_TICK_COUNT_HPP -#define BOOST_WIN32_GET_TICK_COUNT_HPP - -// (C) Copyright 2014 Vicente J. Botet Escriba -// -// 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) - -#include -#include - -namespace boost -{ - namespace detail - { - namespace win32 - { - typedef unsigned long long ticks_type; - typedef ticks_type (__stdcall *gettickcount64fn)(); - typedef unsigned long (__stdcall *gettickcount32fn)(); - ticks_type BOOST_THREAD_DECL GetTickCount64(); - } - } -} - -#include - -#endif diff --git a/include/boost/thread/win32/thread_data.hpp b/include/boost/thread/win32/thread_data.hpp index c0894311..1d4f5727 100644 --- a/include/boost/thread/win32/thread_data.hpp +++ b/include/boost/thread/win32/thread_data.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #ifdef BOOST_THREAD_USES_CHRONO @@ -174,14 +173,14 @@ namespace boost static unsigned long const max_non_infinite_wait=0xfffffffe; timeout(uintmax_t milliseconds_): - start(win32::GetTickCount64()), + start(win32::GetTickCount64()()), milliseconds(milliseconds_), relative(true), abs_time(boost::get_system_time()) {} timeout(boost::system_time const& abs_time_): - start(win32::GetTickCount64()), + start(win32::GetTickCount64()()), milliseconds(0), relative(false), abs_time(abs_time_) @@ -206,7 +205,7 @@ namespace boost } else if(relative) { - win32::ticks_type const now=win32::GetTickCount64(); + win32::ticks_type const now=win32::GetTickCount64()(); win32::ticks_type const elapsed=now-start; return remaining_time((elapsed #include -//#ifndef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64 -//#if _WIN32_WINNT >= 0x0600 && ! defined _WIN32_WINNT_WS08 -//#define BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64 -//#endif -//#endif - #if defined( BOOST_USE_WINDOWS_H ) # include @@ -33,12 +27,6 @@ namespace boost { namespace win32 { -//#ifdef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64 -// typedef unsigned long long ticks_type; -//#else -// typedef unsigned long ticks_type; -//#endif - typedef ULONG_PTR ulong_ptr; typedef HANDLE handle; unsigned const infinite=INFINITE; unsigned const timeout=WAIT_TIMEOUT; @@ -74,12 +62,6 @@ namespace boost using ::SleepEx; using ::Sleep; using ::QueueUserAPC; -// using ::GetTickCount; -//#ifdef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64 -// using ::GetTickCount64; -//#else -// inline ticks_type GetTickCount64() { return GetTickCount(); } -//#endif } } } @@ -114,11 +96,6 @@ namespace boost { namespace win32 { -//#ifdef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64 -// typedef unsigned long long ticks_type; -//#else -// typedef unsigned long ticks_type; -//#endif # ifdef _WIN64 typedef unsigned __int64 ulong_ptr; # else @@ -157,10 +134,6 @@ namespace boost typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr); __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr); -// __declspec(dllimport) unsigned long __stdcall GetTickCount(); -//# ifdef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64 -// __declspec(dllimport) ticks_type __stdcall GetTickCount64(); -//# endif # ifndef UNDER_CE __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId(); __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(); @@ -177,9 +150,6 @@ namespace boost using ::ResetEvent; # endif } -//# ifndef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64 -// inline ticks_type GetTickCount64() { return GetTickCount(); } -//# endif } } } @@ -195,7 +165,88 @@ namespace boost { namespace win32 { - enum event_type + typedef unsigned __int64 ticks_type; + namespace detail { typedef int (__stdcall *farproc_t)(); typedef ticks_type (__stdcall *gettickcount64_t)(); } + extern "C" + { + __declspec(dllimport) detail::farproc_t __stdcall GetProcAddress(void *, const char *); +#if !defined(BOOST_NO_ANSI_APIS) + __declspec(dllimport) void * __stdcall GetModuleHandleA(const char *); +#else + __declspec(dllimport) void * __stdcall GetModuleHandleW(const wchar_t *); +#endif + int __stdcall GetTickCount(); + long _InterlockedCompareExchange(long volatile *, long, long); +#pragma intrinsic(_InterlockedCompareExchange) + } + // Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar + inline ticks_type __stdcall GetTickCount64emulation() + { + static volatile long count = 0xFFFFFFFF; + unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone; + ticks_type current_tick64; + + previous_count = (unsigned long) _InterlockedCompareExchange(&count, 0, 0); + current_tick32 = GetTickCount(); + + if(previous_count == 0xFFFFFFFF) + { + // count has never been written + unsigned long initial_count; + initial_count = current_tick32 >> 28; + previous_count = (unsigned long) _InterlockedCompareExchange(&count, initial_count, 0xFFFFFFFF); + + current_tick64 = initial_count; + current_tick64 <<= 28; + current_tick64 += current_tick32 & 0x0FFFFFFF; + return current_tick64; + } + + previous_count_zone = previous_count & 15; + current_tick32_zone = current_tick32 >> 28; + + if(current_tick32_zone == previous_count_zone) + { + // The top four bits of the 32-bit tick count haven't changed since count was last written. + current_tick64 = previous_count; + current_tick64 <<= 28; + current_tick64 += current_tick32 & 0x0FFFFFFF; + return current_tick64; + } + + if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15)) + { + // The top four bits of the 32-bit tick count have been incremented since count was last written. + _InterlockedCompareExchange(&count, previous_count + 1, previous_count); + current_tick64 = previous_count + 1; + current_tick64 <<= 28; + current_tick64 += current_tick32 & 0x0FFFFFFF; + return current_tick64; + } + + // Oops, we weren't called often enough, we're stuck + return 0xFFFFFFFF; + } + inline detail::gettickcount64_t GetTickCount64() + { + static detail::gettickcount64_t gettickcount64impl; + if(gettickcount64impl) + return gettickcount64impl; + detail::farproc_t addr=GetProcAddress( +#if !defined(BOOST_NO_ANSI_APIS) + GetModuleHandleA("KERNEL32.DLL"), +#else + GetModuleHandleW(L"KERNEL32.DLL"), +#endif + "GetTickCount64"); + if(addr) + gettickcount64impl=(detail::gettickcount64_t) addr; + else + gettickcount64impl=&GetTickCount64emulation; + return gettickcount64impl; + } + + enum event_type { auto_reset_event=false, manual_reset_event=true diff --git a/src/win32/gettickcount64.cpp b/src/win32/gettickcount64.cpp deleted file mode 100644 index 92a999b0..00000000 --- a/src/win32/gettickcount64.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// (C) Copyright 2014 Vicente J. Botet Escriba -// Use, modification and distribution are subject to 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) - -#include - -#include - -#ifdef BOOST_USE_WINDOWS_H -#include -#else -extern "C" -{ - __declspec(dllimport) boost::detail::win32::gettickcount32fn __stdcall GetProcAddress(void *, const char *); - __declspec(dllimport) void * __stdcall GetModuleHandleW(const wchar_t *); -} -#endif - -namespace boost -{ - namespace detail - { - namespace win32 - { - namespace - { - gettickcount64fn gettickcount64 = NULL; - gettickcount32fn gettickcount32 = NULL; - ::boost::once_flag initfnonce = BOOST_ONCE_INIT; - - void init_gettickcount64() - { - gettickcount64 = reinterpret_cast (::GetProcAddress(::GetModuleHandleW(L"Kernel32.dll"), - "GetTickCount64")); - if (!gettickcount64) gettickcount32 = reinterpret_cast (::GetProcAddress( - ::GetModuleHandleW(L"Kernel32.dll"), "GetTickCount")); - } - } - - ticks_type GetTickCount64() - { - ::boost::call_once(&init_gettickcount64, initfnonce); - return gettickcount64 ? gettickcount64() : static_cast (gettickcount32()); - } - } - } -} diff --git a/src/win32/thread.cpp b/src/win32/thread.cpp index f73b404d..54ebbf3e 100644 --- a/src/win32/thread.cpp +++ b/src/win32/thread.cpp @@ -461,7 +461,7 @@ namespace boost LARGE_INTEGER due_time={{0,0}}; if(target_time.relative) { - unsigned long const elapsed_milliseconds=detail::win32::GetTickCount64()-target_time.start; + detail::win32::ticks_type const elapsed_milliseconds=detail::win32::GetTickCount64()()-target_time.start; LONGLONG const remaining_milliseconds=(target_time.milliseconds-elapsed_milliseconds); LONGLONG const hundred_nanoseconds_in_one_millisecond=10000; From 8a7f927be929b0ab2dbc5316338b9d407b0298c9 Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Sat, 5 Jul 2014 19:30:58 +0100 Subject: [PATCH 2/3] Fixed breakage on MSVC. --- example/producer_consumer_bounded.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/producer_consumer_bounded.cpp b/example/producer_consumer_bounded.cpp index b535af34..821aaebf 100644 --- a/example/producer_consumer_bounded.cpp +++ b/example/producer_consumer_bounded.cpp @@ -8,7 +8,7 @@ #define BOOST_THREAD_VERSION 4 #define BOOST_THREAD_QUEUE_DEPRECATE_OLD -#define XXXX +//#define XXXX #include #include From 5c61dced5e57a56172d787d2993be12a7e73725b Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Sat, 5 Jul 2014 19:31:42 +0100 Subject: [PATCH 3/3] Replaced tabs with spaces. --- src/win32/tss_pe.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/win32/tss_pe.cpp b/src/win32/tss_pe.cpp index 053ee900..5fd53b6f 100644 --- a/src/win32/tss_pe.cpp +++ b/src/win32/tss_pe.cpp @@ -287,10 +287,10 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU } #if (_MSC_VER >= 1500) - if( _pRawDllMainOrig ) - { - return _pRawDllMainOrig(hInstance, dwReason, lpReserved); - } + if( _pRawDllMainOrig ) + { + return _pRawDllMainOrig(hInstance, dwReason, lpReserved); + } #endif return true; }