diff --git a/doc/changelog.qbk b/doc/changelog.qbk index 623c8cc..de7c565 100644 --- a/doc/changelog.qbk +++ b/doc/changelog.qbk @@ -13,7 +13,7 @@ [*Bug fixes:] -* Fixed thread id formatting. The thread identifiers could be presented as zeros on some platforms. Also the lower 4 bits of the ids were lost in the output. +* Fixed thread id formatting. The thread identifiers could be presented as zeros on big-endian platforms. Also the lower 4 bits of the ids were lost in the output. [heading 2.4, Boost 1.57] diff --git a/src/thread_id.cpp b/src/thread_id.cpp index 3c347c5..e36bcb5 100644 --- a/src/thread_id.cpp +++ b/src/thread_id.cpp @@ -19,9 +19,11 @@ #include #include -#include #include -#include +#if !defined(BOOST_WINDOWS) +#include +#include +#endif #include #if defined(BOOST_LOG_USE_COMPILER_TLS) #include @@ -80,6 +82,12 @@ BOOST_LOG_OPEN_NAMESPACE namespace aux { +enum +{ + headroom_size = sizeof(pthread_t) > sizeof(uintmax_t) ? 0u : (sizeof(uintmax_t) - sizeof(pthread_t)), + tid_size = sizeof(uintmax_t) - headroom_size +}; + BOOST_LOG_ANONYMOUS_NAMESPACE { //! The function returns current thread identifier @@ -88,20 +96,18 @@ BOOST_LOG_ANONYMOUS_NAMESPACE { // According to POSIX, pthread_t may not be an integer type: // http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/types.h.html // For now we use the hackish cast to get some opaque number that hopefully correlates with system thread identification. - union - { - thread::id::native_type as_uint; - pthread_t as_pthread; - } - caster = {}; - caster.as_pthread = pthread_self(); - return thread::id(caster.as_uint); + thread::id::native_type int_id = 0; + pthread_t pthread_id = pthread_self(); +#if BOOST_ENDIAN_BIG_BYTE || BOOST_ENDIAN_BIG_WORD + std::memcpy(reinterpret_cast< unsigned char* >(&int_id) + headroom_size, &pthread_id, tid_size); +#else + std::memcpy(&int_id, &pthread_id, tid_size); +#endif + return thread::id(int_id); } } // namespace -enum { tid_size = sizeof(pthread_t) > sizeof(uintmax_t) ? sizeof(uintmax_t) : sizeof(pthread_t) }; - } // namespace aux BOOST_LOG_CLOSE_NAMESPACE // namespace log