Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85093 - in branches/release: boost/log boost/log/detail boost/log/utility libs/log libs/log/build libs/log/doc libs/log/src libs/log/test/run
From: andrey.semashev_at_[hidden]
Date: 2013-07-20 14:09:32


Author: andysem
Date: 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013)
New Revision: 85093
URL: http://svn.boost.org/trac/boost/changeset/85093

Log:
Merged recent changes from trunk. Fixes #8730.

Added:
   branches/release/boost/log/detail/malloc_aligned.hpp
      - copied unchanged from r85092, trunk/boost/log/detail/malloc_aligned.hpp
   branches/release/libs/log/src/default_formatter_factory.cpp
      - copied unchanged from r85092, trunk/libs/log/src/default_formatter_factory.cpp
   branches/release/libs/log/src/default_formatter_factory.hpp
      - copied unchanged from r85092, trunk/libs/log/src/default_formatter_factory.hpp
Properties modified:
   branches/release/boost/log/ (props changed)
   branches/release/libs/log/ (props changed)
Text files modified:
   branches/release/boost/log/detail/malloc_aligned.hpp | 134 ++++++++++++++++++++++++++++++++++++++++
   branches/release/boost/log/utility/once_block.hpp | 57 ++++++++--------
   branches/release/libs/log/build/Jamfile.v2 | 1
   branches/release/libs/log/doc/attributes.qbk | 2
   branches/release/libs/log/doc/changelog.qbk | 6 +
   branches/release/libs/log/doc/log.qbk | 3
   branches/release/libs/log/doc/tutorial.qbk | 4
   branches/release/libs/log/src/default_filter_factory.cpp | 4 +
   branches/release/libs/log/src/default_formatter_factory.cpp | 101 ++++++++++++++++++++++++++++++
   branches/release/libs/log/src/default_formatter_factory.hpp | 58 +++++++++++++++++
   branches/release/libs/log/src/filter_parser.cpp | 12 +++
   branches/release/libs/log/src/formatter_parser.cpp | 83 ++++++++---------------
   branches/release/libs/log/src/light_rw_mutex.cpp | 21 +----
   branches/release/libs/log/src/once_block.cpp | 46 +++++++-----
   branches/release/libs/log/src/threadsafe_queue.cpp | 66 +------------------
   branches/release/libs/log/src/timestamp.cpp | 23 ++++--
   branches/release/libs/log/test/run/util_once_block.cpp | 21 ++++-
   17 files changed, 447 insertions(+), 195 deletions(-)

Copied: branches/release/boost/log/detail/malloc_aligned.hpp (from r85092, trunk/boost/log/detail/malloc_aligned.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/log/detail/malloc_aligned.hpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093, copy of r85092, trunk/boost/log/detail/malloc_aligned.hpp)
@@ -0,0 +1,134 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file malloc_aligned.hpp
+ * \author Andrey Semashev
+ * \date 12.07.2013
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/libs/log/doc/log.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_MALLOC_ALIGNED_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_MALLOC_ALIGNED_HPP_INCLUDED_
+
+#include <cstddef>
+#include <cstdlib>
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/log/detail/config.hpp>
+
+// MSVC has its own _aligned_malloc and _aligned_free functions.
+// But MinGW doesn't declare these aligned memory allocation routines for MSVC 6 runtime.
+#if defined(BOOST_WINDOWS) && !(defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0700)
+#include <malloc.h>
+#define BOOST_LOG_HAS_MSVC_ALIGNED_MALLOC 1
+#endif
+
+#if defined(BOOST_HAS_UNISTD_H)
+#include <unistd.h> // _POSIX_VERSION
+#endif
+
+#if defined(__APPLE__) || defined(__APPLE_CC__) || defined(macintosh)
+#include <AvailabilityMacros.h>
+#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)
+// Mac OS X 10.6 and later have posix_memalign
+#define BOOST_LOG_HAS_POSIX_MEMALIGN 1
+#endif
+#elif defined(__ANDROID__)
+// Android NDK (up to release 8e, at least) doesn't have posix_memalign despite it defines POSIX macros as if it does.
+// But we can use memalign() with free() on this platform.
+#include <malloc.h>
+#define BOOST_LOG_HAS_FREEABLE_MEMALIGN 1
+#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200112L)) || (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))
+// Solaris 10 does not have posix_memalign. Solaris 11 and later seem to have it.
+#if !(defined(sun) || defined(__sun)) || defined(__SunOS_5_11) || defined(__SunOS_5_12)
+#define BOOST_LOG_HAS_POSIX_MEMALIGN 1
+#endif
+#endif
+
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_LOG_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef BOOST_LOG_CPU_CACHE_LINE_SIZE
+//! The macro defines the CPU cache line size for the target architecture. This is mostly used for optimization.
+#define BOOST_LOG_CPU_CACHE_LINE_SIZE 64
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+/*!
+ * Allocates uninitialized aligned memory. Memory alignment must be a power of 2 and a multiple of sizeof(void*).
+ * The implementation may impose an upper bound of the alignment as well.
+ */
+inline void* malloc_aligned(std::size_t size, uint32_t alignment)
+{
+#if defined(BOOST_LOG_HAS_POSIX_MEMALIGN)
+ void* p = NULL;
+ if (posix_memalign(&p, alignment, size) != 0)
+ return NULL;
+ return p;
+#elif defined(BOOST_LOG_HAS_FREEABLE_MEMALIGN)
+ return memalign(alignment, size);
+#elif defined(BOOST_LOG_HAS_MSVC_ALIGNED_MALLOC)
+ return _aligned_malloc(size, alignment);
+#else
+ BOOST_ASSERT(alignment >= sizeof(void*));
+ void* p = std::malloc(size + alignment);
+ if (p)
+ {
+ unsigned char* q = static_cast< unsigned char* >(p) + alignment;
+#if defined(BOOST_HAS_INTPTR_T)
+ q = (unsigned char*)((uintptr_t)q & (~(uintptr_t)(alignment - 1u)));
+#else
+ q -= ((std::size_t)q & (std::size_t)(alignment - 1u));
+#endif
+ // Here we assume that the system allocator aligns to 4 bytes at the very least.
+ // Therefore we will always have at least 4 bytes before the aligned pointer.
+ const uint32_t diff = q - static_cast< unsigned char* >(p);
+ p = q;
+ *reinterpret_cast< uint32_t* >(q - 4u) = diff;
+ }
+ return p;
+#endif
+}
+
+/*!
+ * Frees memory allocated with \c malloc_aligned.
+ */
+inline void free_aligned(void* p)
+{
+#if defined(BOOST_LOG_HAS_POSIX_MEMALIGN) || defined(BOOST_LOG_HAS_FREEABLE_MEMALIGN)
+ free(p);
+#elif defined(BOOST_LOG_HAS_MSVC_ALIGNED_MALLOC)
+ _aligned_free(p);
+#else
+ if (p)
+ {
+ unsigned char* const q = static_cast< unsigned char* >(p);
+ const uint32_t diff = *reinterpret_cast< uint32_t* >(q - 4u);
+ std::free(q - diff);
+ }
+#endif
+}
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_MALLOC_ALIGNED_HPP_INCLUDED_

Modified: branches/release/boost/log/utility/once_block.hpp
==============================================================================
--- branches/release/boost/log/utility/once_block.hpp Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/boost/log/utility/once_block.hpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -36,9 +36,10 @@
  * macro. Usage example:
  *
  * <code>
+ * once_block_flag flag = BOOST_LOG_ONCE_BLOCK_INIT;
+ *
  * void foo()
  * {
- * static once_block_flag flag = BOOST_LOG_ONCE_BLOCK_INIT;
  * BOOST_LOG_ONCE_BLOCK_FLAG(flag)
  * {
  * puts("Hello, world once!");
@@ -52,11 +53,11 @@
     // Do not use, implementation detail
     enum
     {
- uninitialized = 0,
+ uninitialized = 0, // this must be zero, so that zero-initialized once_block_flag is equivalent to the one initialized with uninitialized
         being_initialized,
         initialized
- }
- status;
+ };
+ unsigned char status;
 #endif // BOOST_LOG_DOXYGEN_PASS
 };
 
@@ -72,33 +73,33 @@
 class once_block_sentry
 {
 private:
- once_block_flag& m_Flag;
+ once_block_flag& m_flag;
 
 public:
- explicit once_block_sentry(once_block_flag& f) : m_Flag(f)
+ explicit once_block_sentry(once_block_flag& f) BOOST_NOEXCEPT : m_flag(f)
     {
     }
 
- ~once_block_sentry()
+ ~once_block_sentry() BOOST_NOEXCEPT
     {
- if (m_Flag.status != once_block_flag::initialized)
+ if (m_flag.status != once_block_flag::initialized)
             rollback();
     }
 
- bool executed() const
+ bool executed() const BOOST_NOEXCEPT
     {
- return (m_Flag.status == once_block_flag::initialized || enter_once_block());
+ return (m_flag.status == once_block_flag::initialized || enter_once_block());
     }
 
- BOOST_LOG_API void commit();
+ BOOST_LOG_API void commit() BOOST_NOEXCEPT;
 
 private:
- // Non-copyable, non-assignable
- once_block_sentry(once_block_sentry const&);
- once_block_sentry& operator= (once_block_sentry const&);
+ BOOST_LOG_API bool enter_once_block() const BOOST_NOEXCEPT;
+ BOOST_LOG_API void rollback() BOOST_NOEXCEPT;
 
- BOOST_LOG_API bool enter_once_block() const;
- BOOST_LOG_API void rollback();
+ // Non-copyable, non-assignable
+ BOOST_LOG_DELETED_FUNCTION(once_block_sentry(once_block_sentry const&))
+ BOOST_LOG_DELETED_FUNCTION(once_block_sentry& operator= (once_block_sentry const&))
 };
 
 } // namespace aux
@@ -125,27 +126,26 @@
 class once_block_sentry
 {
 private:
- once_block_flag& m_Flag;
+ once_block_flag& m_flag;
 
 public:
- explicit once_block_sentry(once_block_flag& f) : m_Flag(f)
+ explicit once_block_sentry(once_block_flag& f) BOOST_NOEXCEPT : m_flag(f)
     {
     }
 
- bool executed() const
+ bool executed() const BOOST_NOEXCEPT
     {
- return m_Flag.status;
+ return m_flag.status;
     }
 
- void commit()
+ void commit() BOOST_NOEXCEPT
     {
- m_Flag.status = true;
+ m_flag.status = true;
     }
 
-private:
     // Non-copyable, non-assignable
- once_block_sentry(once_block_sentry const&);
- once_block_sentry& operator= (once_block_sentry const&);
+ BOOST_LOG_DELETED_FUNCTION(once_block_sentry(once_block_sentry const&))
+ BOOST_LOG_DELETED_FUNCTION(once_block_sentry& operator= (once_block_sentry const&))
 };
 
 } // namespace aux
@@ -160,10 +160,11 @@
 
 #define BOOST_LOG_ONCE_BLOCK_FLAG_INTERNAL(flag_var, sentry_var)\
     for (boost::log::aux::once_block_sentry sentry_var((flag_var));\
- !sentry_var.executed(); sentry_var.commit())
+ BOOST_UNLIKELY(!sentry_var.executed()); sentry_var.commit())
 
+// NOTE: flag_var deliberately doesn't have an initializer so that it is zero-initialized at the static initialization stage
 #define BOOST_LOG_ONCE_BLOCK_INTERNAL(flag_var, sentry_var)\
- static boost::log::once_block_flag flag_var = BOOST_LOG_ONCE_BLOCK_INIT;\
+ static boost::log::once_block_flag flag_var;\
     BOOST_LOG_ONCE_BLOCK_FLAG_INTERNAL(flag_var, sentry_var)
 
 #endif // BOOST_LOG_DOXYGEN_PASS
@@ -176,7 +177,7 @@
  * been executed.
  */
 #define BOOST_LOG_ONCE_BLOCK_FLAG(flag_var)\
- BOOST_LOG_ONCE_BLOCK_INTERNAL(\
+ BOOST_LOG_ONCE_BLOCK_FLAG_INTERNAL(\
         flag_var,\
         BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_once_block_sentry_))
 

Modified: branches/release/libs/log/build/Jamfile.v2
==============================================================================
--- branches/release/libs/log/build/Jamfile.v2 Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/build/Jamfile.v2 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -344,6 +344,7 @@
     filter_parser.cpp
     formatter_parser.cpp
     default_filter_factory.cpp
+ default_formatter_factory.cpp
     ;
 
 lib boost_log_setup

Modified: branches/release/libs/log/doc/attributes.qbk
==============================================================================
--- branches/release/libs/log/doc/attributes.qbk Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/doc/attributes.qbk 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -296,7 +296,7 @@
 
 [note In order this code to compile, the __boost_exception__ support header has to be included.]
 
-[note We do not inject the [class_attributes_named_scope] attribute into the exception. Since scope stacks are maintained globally, throwing an exception will cause stack unwinding and, as a result, will truncate the global stack. Instead we create a copy of the scope stack bu calling [funcref boost::log::current_scope `current_scope`] at the throw site. This copy will be kept intact even if the global stack instance changes during the stack unwinding.]
+[note We do not inject the [class_attributes_named_scope] attribute into the exception. Since scope stacks are maintained globally, throwing an exception will cause stack unwinding and, as a result, will truncate the global stack. Instead we create a copy of the scope stack by calling [funcref boost::log::current_scope `current_scope`] at the throw site. This copy will be kept intact even if the global stack instance changes during the stack unwinding.]
 
 [endsect]
 

Modified: branches/release/libs/log/doc/changelog.qbk
==============================================================================
--- branches/release/libs/log/doc/changelog.qbk Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/doc/changelog.qbk 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -9,6 +9,12 @@
 
 [section:changelog Changelog]
 
+[heading 2.2, Boost 1.55]
+
+[*General changes:]
+
+* Added a new configuration macro `BOOST_LOG_WITHOUT_DEFAULT_FACTORIES`. By defining this macro the user can disable compilation of the default filter and formatter factories used by settings parsers. This can substantially reduce binary sizes while still retaining support for settings parsers. Note that when this macro is defined the user will have to register _all_ attributes in the library.
+
 [heading 2.1, Boost 1.54]
 
 [*Breaking changes:]

Modified: branches/release/libs/log/doc/log.qbk
==============================================================================
--- branches/release/libs/log/doc/log.qbk Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/doc/log.qbk 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -1,6 +1,6 @@
 [library Boost.Log
     [quickbook 1.5]
- [version 2.0]
+ [version v2]
     [authors [Semashev, Andrey]]
     [copyright 2007 - 2013 Andrey Semashev]
     [license
@@ -200,6 +200,7 @@
     [[`BOOST_LOG_WITHOUT_WCHAR_T`] [If defined, disables support for wide character logging. Affects the compilation of both the library and users' code.]]
     [[`BOOST_LOG_NO_QUERY_PERFORMANCE_COUNTER`] [This macro is only useful on Windows. It affects the compilation of both the library and users' code. If defined, disables support for the `QueryPerformanceCounter` API in the `timer` attribute. This will result in significantly less accurate time readings. The macro is intended to solve possible problems with earlier revisions of AMD Athlon CPU, described [@http://support.microsoft.com/?scid=kb;en-us;895980 here] and [@http://support.microsoft.com/?id=896256 here]. There are also known chipset hardware failures that may prevent this API from functioning properly (see [@http://support.microsoft.com/kb/274323 here]).]]
     [[`BOOST_LOG_USE_NATIVE_SYSLOG`] [Affects only the compilation of the library. If for some reason support for the native SysLog API is not detected automatically, define this macro to forcibly enable it]]
+ [[`BOOST_LOG_WITHOUT_DEFAULT_FACTORIES`] [Affects only the compilation of the library. If defined, the parsers for settings will be built without any default factories for filters and formatters. The user will have to register all attributes in the library before parsing any filters or formatters from strings. This can substantially reduce the binary size.]]
     [[`BOOST_LOG_WITHOUT_SETTINGS_PARSERS`] [Affects only the compilation of the library. If defined, none of the facilities related to the parsers for settings will be built. This can substantially reduce the binary size.]]
     [[`BOOST_LOG_WITHOUT_DEBUG_OUTPUT`] [Affects only the compilation of the library. If defined, the support for debugger output on Windows will not be built.]]
     [[`BOOST_LOG_WITHOUT_EVENT_LOG`] [Affects only the compilation of the library. If defined, the support for Windows event log will not be built. Defining the macro also makes Message Compiler toolset unnecessary.]]

Modified: branches/release/libs/log/doc/tutorial.qbk
==============================================================================
--- branches/release/libs/log/doc/tutorial.qbk Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/doc/tutorial.qbk 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -37,7 +37,7 @@
 
 [@boost:/libs/log/example/doc/tutorial_trivial_flt.cpp See the complete code].
 
-Now, if we run this code sample, the first two log records will be ignored, while the remaining four will pass on to the file.
+Now, if we run this code sample, the first two log records will be ignored, while the remaining four will pass on to the console.
 
 [important Remember that the streaming expression is only executed if the record passed filtering. Don't specify business-critical calls in the streaming expression, as these calls may not get invoked if the record is filtered away.]
 
@@ -350,7 +350,7 @@
 
 The library supports logging strings containing national characters. There are basically two ways of doing this. On UNIX-like systems typically some multibyte character encoding (e.g. UTF-8) is used to represent national characters. In this case the library can be used just the way it is used for plain ASCII logging, no additional setup is required.
 
-On Windows the common practice is to use wide strings to represent national characters. Also, most of the system API is wide character oriented, which requires Windows-specific sinks to also support wide strings. On the other hand, generic sinks, like [link log.detailed.sink_backends.text_file text file sink, are byte-oriented (because, well, you store bytes in files, not characters). This forces the library to perform character code conversion when needed by the sink. To set up the library for this one has to imbue the sink with a locale with the appropriate `codecvt` facet. __boost_locale__ can be used to generate such a locale. Let's see an example:
+On Windows the common practice is to use wide strings to represent national characters. Also, most of the system API is wide character oriented, which requires Windows-specific sinks to also support wide strings. On the other hand, generic sinks, like the [link log.detailed.sink_backends.text_file text file sink], are byte-oriented (because, well, you store bytes in files, not characters). This forces the library to perform character code conversion when needed by the sink. To set up the library for this one has to imbue the sink with a locale with the appropriate `codecvt` facet. __boost_locale__ can be used to generate such a locale. Let's see an example:
 
 [example_wide_char_logging_initialization]
 

Modified: branches/release/libs/log/src/default_filter_factory.cpp
==============================================================================
--- branches/release/libs/log/src/default_filter_factory.cpp Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/src/default_filter_factory.cpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -13,6 +13,8 @@
  * at http://www.boost.org/libs/log/doc/log.html.
  */
 
+#if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
+
 #include <string>
 #include <boost/move/core.hpp>
 #include <boost/move/utility.hpp>
@@ -395,3 +397,5 @@
 } // namespace boost
 
 #include <boost/log/detail/footer.hpp>
+
+#endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)

Copied: branches/release/libs/log/src/default_formatter_factory.cpp (from r85092, trunk/libs/log/src/default_formatter_factory.cpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/libs/log/src/default_formatter_factory.cpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093, copy of r85092, trunk/libs/log/src/default_formatter_factory.cpp)
@@ -0,0 +1,101 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file default_formatter_factory.hpp
+ * \author Andrey Semashev
+ * \date 14.07.2013
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/libs/log/doc/log.html.
+ */
+
+#if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
+
+#undef BOOST_MPL_LIMIT_VECTOR_SIZE
+#define BOOST_MPL_LIMIT_VECTOR_SIZE 50
+
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/copy.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/back_inserter.hpp>
+#include <boost/date_time/gregorian/gregorian.hpp>
+#include <boost/date_time/local_time/local_time.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/phoenix/core.hpp>
+#include <boost/phoenix/operator.hpp>
+#include <boost/log/exceptions.hpp>
+#include <boost/log/expressions/attr.hpp>
+#include <boost/log/expressions/formatters/stream.hpp>
+#include <boost/log/utility/type_dispatch/standard_types.hpp>
+#include <boost/log/utility/type_dispatch/date_time_types.hpp>
+#include <boost/log/utility/string_literal.hpp>
+#include <boost/log/detail/code_conversion.hpp>
+#include <boost/log/detail/process_id.hpp>
+#if !defined(BOOST_LOG_NO_THREADS)
+#include <boost/log/detail/thread_id.hpp>
+#endif
+#include <boost/log/attributes/named_scope.hpp>
+#include "default_formatter_factory.hpp"
+#include <boost/log/detail/header.hpp>
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! The callback for equality relation filter
+template< typename CharT >
+typename default_formatter_factory< CharT >::formatter_type
+default_formatter_factory< CharT >::create_formatter(attribute_name const& name, args_map const& args)
+{
+ // No user-defined factory, shall use the most generic formatter we can ever imagine at this point
+ typedef mpl::copy<
+ // We have to exclude std::time_t since it's an integral type and will conflict with one of the standard types
+ boost_time_period_types,
+ mpl::back_inserter<
+ mpl::copy<
+ boost_time_duration_types,
+ mpl::back_inserter< boost_date_time_types >
+ >::type
+ >
+ >::type time_related_types;
+
+ typedef mpl::copy<
+ mpl::copy<
+ mpl::vector<
+ attributes::named_scope_list,
+#if !defined(BOOST_LOG_NO_THREADS)
+ log::aux::thread::id,
+#endif
+ log::aux::process::id
+ >,
+ mpl::back_inserter< time_related_types >
+ >::type,
+ mpl::back_inserter< default_attribute_types >
+ >::type supported_types;
+
+ return formatter_type(expressions::stream << expressions::attr< supported_types::type >(name));
+}
+
+// Explicitly instantiate factory implementation
+#ifdef BOOST_LOG_USE_CHAR
+template class default_formatter_factory< char >;
+#endif
+#ifdef BOOST_LOG_USE_WCHAR_T
+template class default_formatter_factory< wchar_t >;
+#endif
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)

Copied: branches/release/libs/log/src/default_formatter_factory.hpp (from r85092, trunk/libs/log/src/default_formatter_factory.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/libs/log/src/default_formatter_factory.hpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093, copy of r85092, trunk/libs/log/src/default_formatter_factory.hpp)
@@ -0,0 +1,58 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file default_formatter_factory.hpp
+ * \author Andrey Semashev
+ * \date 14.07.2013
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/libs/log/doc/log.html.
+ */
+
+#ifndef BOOST_DEFAULT_FORMATTER_FACTORY_HPP_INCLUDED_
+#define BOOST_DEFAULT_FORMATTER_FACTORY_HPP_INCLUDED_
+
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/utility/setup/formatter_parser.hpp>
+#include <boost/log/detail/header.hpp>
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! The default filter factory that supports creating filters for the standard types (see utility/type_dispatch/standard_types.hpp)
+template< typename CharT >
+class default_formatter_factory :
+ public formatter_factory< CharT >
+{
+ //! Base type
+ typedef formatter_factory< CharT > base_type;
+ //! Self type
+ typedef default_formatter_factory< CharT > this_type;
+
+public:
+ // Type imports
+ typedef typename base_type::char_type char_type;
+ typedef typename base_type::string_type string_type;
+ typedef typename base_type::formatter_type formatter_type;
+ typedef typename base_type::args_map args_map;
+
+ //! The function creates a formatter for the specified attribute.
+ virtual formatter_type create_formatter(attribute_name const& name, args_map const& args);
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_DEFAULT_FORMATTER_FACTORY_HPP_INCLUDED_

Modified: branches/release/libs/log/src/filter_parser.cpp
==============================================================================
--- branches/release/libs/log/src/filter_parser.cpp Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/src/filter_parser.cpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -48,7 +48,9 @@
 #include <boost/log/detail/light_rw_mutex.hpp>
 #endif // !defined(BOOST_LOG_NO_THREADS)
 #include "parser_utils.hpp"
+#if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
 #include "default_filter_factory.hpp"
+#endif
 #include "spirit_encoding.hpp"
 #include <boost/log/detail/header.hpp>
 
@@ -94,17 +96,27 @@
 #endif
     //! The map of filter factories
     factories_map m_Map;
+#if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
     //! Default factory
     mutable aux::default_filter_factory< char_type > m_DefaultFactory;
+#endif
 
     //! The method returns the filter factory for the specified attribute name
     filter_factory_type& get_factory(attribute_name const& name) const
     {
         typename factories_map::const_iterator it = m_Map.find(name);
         if (it != m_Map.end())
+ {
             return *it->second;
+ }
         else
+ {
+#if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
             return m_DefaultFactory;
+#else
+ BOOST_LOG_THROW_DESCR(setup_error, "No filter factory registered for attribute " + name.string());
+#endif
+ }
     }
 
 private:

Modified: branches/release/libs/log/src/formatter_parser.cpp
==============================================================================
--- branches/release/libs/log/src/formatter_parser.cpp Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/src/formatter_parser.cpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -15,9 +15,6 @@
 
 #ifndef BOOST_LOG_WITHOUT_SETTINGS_PARSERS
 
-#undef BOOST_MPL_LIMIT_VECTOR_SIZE
-#define BOOST_MPL_LIMIT_VECTOR_SIZE 50
-
 #include <ctime>
 #include <map>
 #include <string>
@@ -27,10 +24,6 @@
 #include <boost/bind.hpp>
 #include <boost/move/core.hpp>
 #include <boost/move/utility.hpp>
-#include <boost/mpl/vector.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/push_back.hpp>
-#include <boost/mpl/back_inserter.hpp>
 #include <boost/optional/optional.hpp>
 #include <boost/utility/in_place_factory.hpp>
 #include <boost/range/iterator_range_core.hpp>
@@ -43,30 +36,24 @@
 #include <boost/spirit/include/qi_symbols.hpp>
 #include <boost/phoenix/core.hpp>
 #include <boost/phoenix/operator.hpp>
-#include <boost/date_time/gregorian/gregorian.hpp>
-#include <boost/date_time/local_time/local_time.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/log/expressions/attr.hpp>
 #include <boost/log/expressions/message.hpp>
 #include <boost/log/expressions/formatters/stream.hpp>
 #include <boost/log/attributes/attribute_name.hpp>
-#include <boost/log/attributes/named_scope.hpp>
 #include <boost/log/exceptions.hpp>
 #include <boost/log/detail/singleton.hpp>
-#include <boost/log/detail/process_id.hpp>
 #include <boost/log/detail/code_conversion.hpp>
 #include <boost/log/detail/default_attribute_names.hpp>
 #include <boost/log/utility/functional/nop.hpp>
 #include <boost/log/utility/setup/formatter_parser.hpp>
-#include <boost/log/utility/type_dispatch/standard_types.hpp>
-#include <boost/log/utility/type_dispatch/date_time_types.hpp>
 #if !defined(BOOST_LOG_NO_THREADS)
-#include <boost/log/detail/thread_id.hpp>
 #include <boost/log/detail/locks.hpp>
 #include <boost/log/detail/light_rw_mutex.hpp>
 #endif
 #include "parser_utils.hpp"
 #include "spirit_encoding.hpp"
+#if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
+#include "default_formatter_factory.hpp"
+#endif
 #include <boost/log/detail/header.hpp>
 
 namespace qi = boost::spirit::qi;
@@ -91,7 +78,8 @@
     friend class base_type;
 #endif
 
- typedef formatter_factory< CharT > formatter_factory_type;
+ typedef CharT char_type;
+ typedef formatter_factory< char_type > formatter_factory_type;
 
     //! Attribute name ordering predicate
     struct attribute_name_order
@@ -113,6 +101,28 @@
 #endif
     //! The map of formatter factories
     factories_map m_Map;
+#if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
+ //! Default factory
+ mutable aux::default_formatter_factory< char_type > m_DefaultFactory;
+#endif
+
+ //! The method returns the filter factory for the specified attribute name
+ formatter_factory_type& get_factory(attribute_name const& name) const
+ {
+ typename factories_map::const_iterator it = m_Map.find(name);
+ if (it != m_Map.end())
+ {
+ return *it->second;
+ }
+ else
+ {
+#if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
+ return m_DefaultFactory;
+#else
+ BOOST_LOG_THROW_DESCR(setup_error, "No formatter factory registered for attribute " + name.string());
+#endif
+ }
+ }
 
 private:
     formatters_repository()
@@ -326,43 +336,10 @@
         }
         else
         {
+ // Use the factory to create the formatter
             formatters_repository< char_type > const& repo = formatters_repository< char_type >::get();
- typename formatters_repository< char_type >::factories_map::const_iterator it = repo.m_Map.find(m_AttrName);
- if (it != repo.m_Map.end())
- {
- // We've found a user-defined factory for this attribute
- append_formatter(it->second->create_formatter(m_AttrName, m_FactoryArgs));
- }
- else
- {
- // No user-defined factory, shall use the most generic formatter we can ever imagine at this point
- typedef mpl::copy<
- // We have to exclude std::time_t since it's an integral type and will conflict with one of the standard types
- boost_time_period_types,
- mpl::back_inserter<
- mpl::copy<
- boost_time_duration_types,
- mpl::back_inserter< boost_date_time_types >
- >::type
- >
- >::type time_related_types;
-
- typedef mpl::copy<
- mpl::copy<
- mpl::vector<
- attributes::named_scope_list,
-#if !defined(BOOST_LOG_NO_THREADS)
- log::aux::thread::id,
-#endif
- log::aux::process::id
- >,
- mpl::back_inserter< time_related_types >
- >::type,
- mpl::back_inserter< default_attribute_types >
- >::type supported_types;
-
- append_formatter(expressions::stream << expressions::attr< supported_types::type >(m_AttrName));
- }
+ formatter_factory_type& factory = repo.get_factory(m_AttrName);
+ append_formatter(factory.create_formatter(m_AttrName, m_FactoryArgs));
         }
 
         // Eventually, clear all the auxiliary data

Modified: branches/release/libs/log/src/light_rw_mutex.cpp
==============================================================================
--- branches/release/libs/log/src/light_rw_mutex.cpp Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/src/light_rw_mutex.cpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -25,20 +25,13 @@
 #include <boost/assert.hpp>
 #include <boost/thread/shared_mutex.hpp>
 #include <boost/log/utility/once_block.hpp>
+#include <boost/log/detail/malloc_aligned.hpp>
 
 #include "windows_version.hpp"
 #include <windows.h>
-#include <malloc.h>
 
 #include <boost/log/detail/header.hpp>
 
-#if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0700
-// MinGW doesn't declare aligned memory allocation routines for MSVC 6 runtime
-inline void* _aligned_malloc(size_t size, size_t) { return malloc(size); }
-inline void _aligned_free(void* p) { free(p); }
-#endif
-
-
 namespace boost {
 
 BOOST_LOG_OPEN_NAMESPACE
@@ -67,17 +60,15 @@
     // To avoid cache line aliasing we do aligned memory allocation here
     enum
     {
- // Cache line size on x86
- cache_line_size = 64,
         // Allocation size is the minimum number of cache lines to accommodate shared_mutex
         size =
             (
- sizeof(shared_mutex) / cache_line_size
- + ((sizeof(shared_mutex) % cache_line_size) != 0)
+ sizeof(shared_mutex) / BOOST_LOG_CPU_CACHE_LINE_SIZE
+ + ((sizeof(shared_mutex) % BOOST_LOG_CPU_CACHE_LINE_SIZE) != 0)
             )
- * cache_line_size
+ * BOOST_LOG_CPU_CACHE_LINE_SIZE
     };
- mtx->p = _aligned_malloc(size, cache_line_size);
+ mtx->p = malloc_aligned(size, BOOST_LOG_CPU_CACHE_LINE_SIZE);
     BOOST_ASSERT(mtx->p != NULL);
     new (mtx->p) shared_mutex();
 }
@@ -85,7 +76,7 @@
 void __stdcall DeinitializeSharedMutex(mutex_impl* mtx)
 {
     static_cast< shared_mutex* >(mtx->p)->~shared_mutex();
- _aligned_free(mtx->p);
+ free_aligned(mtx->p);
     mtx->p = NULL;
 }
 

Modified: branches/release/libs/log/src/once_block.cpp
==============================================================================
--- branches/release/libs/log/src/once_block.cpp Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/src/once_block.cpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -18,6 +18,7 @@
 #include <boost/log/utility/once_block.hpp>
 #ifndef BOOST_LOG_NO_THREADS
 
+#include <cstdlib>
 #include <boost/assert.hpp>
 
 #if defined(BOOST_THREAD_PLATFORM_WIN32)
@@ -42,11 +43,11 @@
 
 } // namespace
 
-BOOST_LOG_API bool once_block_sentry::enter_once_block() const
+BOOST_LOG_API bool once_block_sentry::enter_once_block() const BOOST_NOEXCEPT
 {
     AcquireSRWLockExclusive(&g_OnceBlockMutex);
 
- once_block_flag volatile& flag = m_Flag;
+ once_block_flag volatile& flag = m_flag;
     while (flag.status != once_block_flag::initialized)
     {
         if (flag.status == once_block_flag::uninitialized)
@@ -72,23 +73,23 @@
     return true;
 }
 
-BOOST_LOG_API void once_block_sentry::commit()
+BOOST_LOG_API void once_block_sentry::commit() BOOST_NOEXCEPT
 {
     AcquireSRWLockExclusive(&g_OnceBlockMutex);
 
     // The initializer executed successfully
- m_Flag.status = once_block_flag::initialized;
+ m_flag.status = once_block_flag::initialized;
 
     ReleaseSRWLockExclusive(&g_OnceBlockMutex);
     WakeAllConditionVariable(&g_OnceBlockCond);
 }
 
-BOOST_LOG_API void once_block_sentry::rollback()
+BOOST_LOG_API void once_block_sentry::rollback() BOOST_NOEXCEPT
 {
     AcquireSRWLockExclusive(&g_OnceBlockMutex);
 
     // The initializer failed, marking the flag as if it hasn't run at all
- m_Flag.status = once_block_flag::uninitialized;
+ m_flag.status = once_block_flag::uninitialized;
 
     ReleaseSRWLockExclusive(&g_OnceBlockMutex);
     WakeAllConditionVariable(&g_OnceBlockCond);
@@ -328,10 +329,10 @@
         delete impl;
     }
 
- once_block_impl_base* get_once_block_impl()
+ once_block_impl_base* get_once_block_impl() BOOST_NOEXCEPT
     {
         once_block_impl_base* impl = g_pOnceBlockImpl;
- if (!impl)
+ if (!impl) try
         {
             once_block_impl_base* new_impl = create_once_block_impl();
             impl = (once_block_impl_base*)
@@ -346,25 +347,30 @@
                 return new_impl;
             }
         }
+ catch (...)
+ {
+ BOOST_ASSERT_MSG(false, "Boost.Log: Failed to initialize the once block thread synchronization structures");
+ std::abort();
+ }
 
         return impl;
     }
 
 } // namespace
 
-BOOST_LOG_API bool once_block_sentry::enter_once_block() const
+BOOST_LOG_API bool once_block_sentry::enter_once_block() const BOOST_NOEXCEPT
 {
- return get_once_block_impl()->enter_once_block(m_Flag);
+ return get_once_block_impl()->enter_once_block(m_flag);
 }
 
-BOOST_LOG_API void once_block_sentry::commit()
+BOOST_LOG_API void once_block_sentry::commit() BOOST_NOEXCEPT
 {
- get_once_block_impl()->commit(m_Flag);
+ get_once_block_impl()->commit(m_flag);
 }
 
-BOOST_LOG_API void once_block_sentry::rollback()
+BOOST_LOG_API void once_block_sentry::rollback() BOOST_NOEXCEPT
 {
- get_once_block_impl()->rollback(m_Flag);
+ get_once_block_impl()->rollback(m_flag);
 }
 
 } // namespace aux
@@ -395,11 +401,11 @@
 
 } // namespace
 
-BOOST_LOG_API bool once_block_sentry::enter_once_block() const
+BOOST_LOG_API bool once_block_sentry::enter_once_block() const BOOST_NOEXCEPT
 {
     BOOST_VERIFY(!pthread_mutex_lock(&g_OnceBlockMutex));
 
- once_block_flag volatile& flag = m_Flag;
+ once_block_flag volatile& flag = m_flag;
     while (flag.status != once_block_flag::initialized)
     {
         if (flag.status == once_block_flag::uninitialized)
@@ -424,23 +430,23 @@
     return true;
 }
 
-BOOST_LOG_API void once_block_sentry::commit()
+BOOST_LOG_API void once_block_sentry::commit() BOOST_NOEXCEPT
 {
     BOOST_VERIFY(!pthread_mutex_lock(&g_OnceBlockMutex));
 
     // The initializer executed successfully
- m_Flag.status = once_block_flag::initialized;
+ m_flag.status = once_block_flag::initialized;
 
     BOOST_VERIFY(!pthread_mutex_unlock(&g_OnceBlockMutex));
     BOOST_VERIFY(!pthread_cond_broadcast(&g_OnceBlockCond));
 }
 
-BOOST_LOG_API void once_block_sentry::rollback()
+BOOST_LOG_API void once_block_sentry::rollback() BOOST_NOEXCEPT
 {
     BOOST_VERIFY(!pthread_mutex_lock(&g_OnceBlockMutex));
 
     // The initializer failed, marking the flag as if it hasn't run at all
- m_Flag.status = once_block_flag::uninitialized;
+ m_flag.status = once_block_flag::uninitialized;
 
     BOOST_VERIFY(!pthread_mutex_unlock(&g_OnceBlockMutex));
     BOOST_VERIFY(!pthread_cond_broadcast(&g_OnceBlockCond));

Modified: branches/release/libs/log/src/threadsafe_queue.cpp
==============================================================================
--- branches/release/libs/log/src/threadsafe_queue.cpp Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/src/threadsafe_queue.cpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -25,44 +25,14 @@
 
 #ifndef BOOST_LOG_NO_THREADS
 
-#include <stdlib.h>
 #include <new>
 #include <boost/assert.hpp>
-#include <boost/static_assert.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/type_traits/alignment_of.hpp>
 #include <boost/log/detail/spin_mutex.hpp>
 #include <boost/log/detail/locks.hpp>
 #include <boost/log/detail/alignas.hpp>
-
-#if defined(BOOST_HAS_UNISTD_H)
-#include <unistd.h> // _POSIX_VERSION
-#endif
-
-#if defined(BOOST_HAS_STDINT_H)
-#include <stdint.h> // uintptr_t
-#else
-// MSVC defines integer types here
-#include <stddef.h> // uintptr_t
-#endif
-
-#if defined(__APPLE__) || defined(__APPLE_CC__) || defined(macintosh)
-#include <AvailabilityMacros.h>
-#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)
-// Mac OS X 10.6 and later have posix_memalign
-#define BOOST_LOG_HAS_POSIX_MEMALIGN 1
-#endif
-#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200112L)) || (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))
-// Solaris 10 does not have posix_memalign. Solaris 11 and later seem to have it.
-#if !(defined(sun) || defined(__sun)) || defined(__SunOS_5_11) || defined(__SunOS_5_12)
-#define BOOST_LOG_HAS_POSIX_MEMALIGN 1
-#endif
-#endif
-
-#if defined(BOOST_WINDOWS)
-#include <malloc.h> // _aligned_malloc, _aligned_free
-#endif
-
+#include <boost/log/detail/malloc_aligned.hpp>
 #include <boost/log/detail/header.hpp>
 
 namespace boost {
@@ -81,9 +51,9 @@
 
     /*!
      * A structure that contains a pointer to the node and the associated mutex.
- * The alignment below allows to eliminate false sharing, it should be not less than CPU cache line size (which is assumed to be 64 bytes in most cases).
+ * The alignment below allows to eliminate false sharing, it should not be less than CPU cache line size.
      */
- struct BOOST_LOG_ALIGNAS(64) pointer
+ struct BOOST_LOG_ALIGNAS(BOOST_LOG_CPU_CACHE_LINE_SIZE) pointer
     {
         //! Pointer to the either end of the queue
         node_base* node;
@@ -168,41 +138,15 @@
 
 BOOST_LOG_API void* threadsafe_queue_impl::operator new (std::size_t size)
 {
- void* p = NULL;
-
-#if defined(BOOST_LOG_HAS_POSIX_MEMALIGN)
- if (posix_memalign(&p, 64, size) || !p)
- BOOST_THROW_EXCEPTION(std::bad_alloc());
- return p;
-#elif defined(BOOST_WINDOWS)
- p = _aligned_malloc(size, 64);
- if (!p)
- BOOST_THROW_EXCEPTION(std::bad_alloc());
-#else
- p = malloc(size + 64);
+ void* p = malloc_aligned(size, BOOST_LOG_CPU_CACHE_LINE_SIZE);
     if (!p)
         BOOST_THROW_EXCEPTION(std::bad_alloc());
- unsigned char* q = static_cast< unsigned char* >(p) + 64;
- q = (unsigned char*)((uintptr_t)q & (~(uintptr_t)63));
- const unsigned char diff = q - static_cast< unsigned char* >(p);
- p = q;
- *--q = diff;
-#endif
-
     return p;
 }
 
 BOOST_LOG_API void threadsafe_queue_impl::operator delete (void* p, std::size_t)
 {
-#if defined(BOOST_LOG_HAS_POSIX_MEMALIGN)
- free(p);
-#elif defined(BOOST_WINDOWS)
- _aligned_free(p);
-#else
- unsigned char* q = static_cast< unsigned char* >(p);
- const unsigned char diff = *--q;
- free(static_cast< unsigned char* >(p) - diff);
-#endif
+ free_aligned(p);
 }
 
 } // namespace aux

Modified: branches/release/libs/log/src/timestamp.cpp
==============================================================================
--- branches/release/libs/log/src/timestamp.cpp Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/src/timestamp.cpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -20,12 +20,6 @@
 #include <boost/detail/interlocked.hpp>
 #include "windows_version.hpp"
 #include <windows.h>
-#if (defined(_MSC_VER) && defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2) || (defined(__GNUC__) && defined(__i386__) && defined(__SSE2__))
-#include <emmintrin.h>
-#if defined(_MSC_VER)
-#include <intrin.h>
-#endif
-#endif
 #else
 #include <unistd.h> // for config macros
 #if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
@@ -65,7 +59,13 @@
 //! Atomically loads and stores the 64-bit value through SSE2 instructions
 BOOST_LOG_FORCEINLINE void move64(const uint64_t* from, uint64_t* to)
 {
- _mm_storel_epi64(reinterpret_cast< __m128i* >(to), _mm_loadl_epi64(reinterpret_cast< const __m128i* >(from)));
+ __asm
+ {
+ mov eax, from
+ mov edx, to
+ movq xmm4, qword ptr [eax]
+ movq qword ptr [edx], xmm4
+ };
 }
 # else // defined(_M_IX86_FP) && _M_IX86_FP >= 2
 //! Atomically loads and stores the 64-bit value through FPU instructions
@@ -97,7 +97,14 @@
 //! Atomically loads and stores the 64-bit value through SSE2 instructions
 BOOST_LOG_FORCEINLINE void move64(const uint64_t* from, uint64_t* to)
 {
- _mm_storel_epi64(reinterpret_cast< __m128i* >(to), _mm_loadl_epi64(reinterpret_cast< const __m128i* >(from)));
+ __asm__ __volatile__
+ (
+ "movq %1, %%xmm4\n\t"
+ "movq %%xmm4, %0\n\t"
+ : "=m" (*to)
+ : "m" (*from)
+ : "memory", "xmm4"
+ );
 }
 # else // defined(__SSE2__)
 //! Atomically loads and stores the 64-bit value through FPU instructions

Modified: branches/release/libs/log/test/run/util_once_block.cpp
==============================================================================
--- branches/release/libs/log/test/run/util_once_block.cpp Sat Jul 20 14:01:35 2013 (r85092)
+++ branches/release/libs/log/test/run/util_once_block.cpp 2013-07-20 14:09:32 EDT (Sat, 20 Jul 2013) (r85093)
@@ -21,9 +21,12 @@
 
 #if !defined(BOOST_LOG_NO_THREADS)
 
+#include <boost/ref.hpp>
+#include <boost/bind.hpp>
 #include <boost/thread/thread.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/locks.hpp>
+#include <boost/thread/barrier.hpp>
 
 namespace logging = boost::log;
 
@@ -47,9 +50,10 @@
 }
 
 
-void once_block_flag_thread()
+void once_block_flag_thread(boost::barrier& barrier)
 {
     int my_once_value = 0;
+ barrier.wait();
     for (unsigned int i = 0; i < LOOP_COUNT; ++i)
     {
         BOOST_LOG_ONCE_BLOCK_FLAG(flag)
@@ -71,12 +75,13 @@
 BOOST_AUTO_TEST_CASE(once_block_flag)
 {
     boost::thread_group group;
+ boost::barrier barrier(static_cast< unsigned int >(THREAD_COUNT));
 
     try
     {
         for (unsigned int i = 0; i < THREAD_COUNT; ++i)
         {
- group.create_thread(&once_block_flag_thread);
+ group.create_thread(boost::bind(&once_block_flag_thread, boost::ref(barrier)));
         }
         group.join_all();
     }
@@ -92,9 +97,10 @@
 
 int var_to_init_once = 0;
 
-void once_block_thread()
+void once_block_thread(boost::barrier& barrier)
 {
     int my_once_value = 0;
+ barrier.wait();
     for (unsigned int i = 0; i < LOOP_COUNT; ++i)
     {
         BOOST_LOG_ONCE_BLOCK()
@@ -118,12 +124,13 @@
 BOOST_AUTO_TEST_CASE(once_block)
 {
     boost::thread_group group;
+ boost::barrier barrier(static_cast< unsigned int >(THREAD_COUNT));
 
     try
     {
         for (unsigned int i = 0; i < THREAD_COUNT; ++i)
         {
- group.create_thread(&once_block_thread);
+ group.create_thread(boost::bind(&once_block_thread, boost::ref(barrier)));
         }
         group.join_all();
     }
@@ -145,8 +152,9 @@
 unsigned int pass_counter = 0;
 unsigned int exception_counter = 0;
 
-void once_block_with_exception_thread()
+void once_block_with_exception_thread(boost::barrier& barrier)
 {
+ barrier.wait();
     try
     {
         BOOST_LOG_ONCE_BLOCK()
@@ -170,12 +178,13 @@
 BOOST_AUTO_TEST_CASE(once_block_retried_on_exception)
 {
     boost::thread_group group;
+ boost::barrier barrier(static_cast< unsigned int >(THREAD_COUNT));
 
     try
     {
         for (unsigned int i = 0; i < THREAD_COUNT; ++i)
         {
- group.create_thread(&once_block_with_exception_thread);
+ group.create_thread(boost::bind(&once_block_with_exception_thread, boost::ref(barrier)));
         }
         group.join_all();
     }


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