]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/log/src/event.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / log / src / event.cpp
index 5485154d7210b1ca412adb09a8d63794a0c22f3f..bbc033e7a2a9fcd1b3328886f756d3aaf7b40f4d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *          Copyright Andrey Semashev 2007 - 2015.
+ *          Copyright Andrey Semashev 2007 - 2021.
  * 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 <boost/log/detail/event.hpp>
 #include <boost/log/exceptions.hpp>
 
-#if defined(BOOST_LOG_EVENT_USE_FUTEX)
+#if defined(BOOST_LOG_EVENT_USE_ATOMIC)
 
-#include <stddef.h>
-#include <errno.h>
-#include <sys/syscall.h>
-#include <linux/futex.h>
 #include <boost/memory_order.hpp>
-
-// Some Android NDKs (Google NDK and older Crystax.NET NDK versions) don't define SYS_futex
-#if defined(SYS_futex)
-#define BOOST_LOG_SYS_FUTEX SYS_futex
-#else
-#define BOOST_LOG_SYS_FUTEX __NR_futex
-#endif
-
-#if defined(FUTEX_WAIT_PRIVATE)
-#define BOOST_LOG_FUTEX_WAIT FUTEX_WAIT_PRIVATE
-#else
-#define BOOST_LOG_FUTEX_WAIT FUTEX_WAIT
-#endif
-
-#if defined(FUTEX_WAKE_PRIVATE)
-#define BOOST_LOG_FUTEX_WAKE FUTEX_WAKE_PRIVATE
-#else
-#define BOOST_LOG_FUTEX_WAKE FUTEX_WAKE
-#endif
+#include <boost/atomic/atomic.hpp>
+#include <boost/atomic/fences.hpp>
 
 #elif defined(BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE)
 
@@ -60,7 +39,9 @@
 #elif defined(BOOST_LOG_EVENT_USE_WINAPI)
 
 #include <windows.h>
-#include <boost/detail/interlocked.hpp>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/atomic.hpp>
+#include <boost/atomic/fences.hpp>
 
 #else
 
@@ -76,57 +57,27 @@ BOOST_LOG_OPEN_NAMESPACE
 
 namespace aux {
 
-#if defined(BOOST_LOG_EVENT_USE_FUTEX)
-
-//! Default constructor
-BOOST_LOG_API futex_based_event::futex_based_event() : m_state(0)
-{
-}
-
-//! Destructor
-BOOST_LOG_API futex_based_event::~futex_based_event()
-{
-}
+#if defined(BOOST_LOG_EVENT_USE_ATOMIC)
 
 //! Waits for the object to become signalled
-BOOST_LOG_API void futex_based_event::wait()
+BOOST_LOG_API void atomic_based_event::wait()
 {
-    if (m_state.exchange(0, boost::memory_order_acq_rel) == 0)
+    while (m_state.exchange(0u, boost::memory_order_acq_rel) == 0u)
     {
-        while (true)
-        {
-            if (::syscall(BOOST_LOG_SYS_FUTEX, &m_state.value(), BOOST_LOG_FUTEX_WAIT, 0, NULL, NULL, 0) == 0)
-            {
-                // Another thread has set the event while sleeping
-                break;
-            }
-
-            const int err = errno;
-            if (err == EWOULDBLOCK)
-            {
-                // Another thread has set the event before sleeping
-                break;
-            }
-            else if (BOOST_UNLIKELY(err != EINTR))
-            {
-                BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to block on the futex", (err));
-            }
-        }
-
-        m_state.store(0, boost::memory_order_relaxed);
+        m_state.wait(0u, boost::memory_order_relaxed);
     }
 }
 
 //! Sets the object to a signalled state
-BOOST_LOG_API void futex_based_event::set_signalled()
+BOOST_LOG_API void atomic_based_event::set_signalled()
 {
-    if (m_state.exchange(1, boost::memory_order_release) == 0)
+    if (m_state.load(boost::memory_order_relaxed) != 0u)
     {
-        if (BOOST_UNLIKELY(::syscall(BOOST_LOG_SYS_FUTEX, &m_state.value(), BOOST_LOG_FUTEX_WAKE, 1, NULL, NULL, 0) < 0))
-        {
-            const int err = errno;
-            BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to wake threads blocked on the futex", (err));
-        }
+        boost::atomic_thread_fence(boost::memory_order_release);
+    }
+    else if (m_state.exchange(1u, boost::memory_order_release) == 0u)
+    {
+        m_state.notify_one();
     }
 }
 
@@ -185,47 +136,73 @@ BOOST_LOG_API void sem_based_event::set_signalled()
 
 //! Default constructor
 BOOST_LOG_API winapi_based_event::winapi_based_event() :
-    m_state(0),
-    m_event(CreateEventA(NULL, false, false, NULL))
+    m_state(0u),
+    m_event(NULL)
 {
-    if (BOOST_UNLIKELY(!m_event))
+    if (!m_state.has_native_wait_notify())
     {
-        const DWORD err = GetLastError();
-        BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to create Windows event", (err));
+        m_event = CreateEventA(NULL, false, false, NULL);
+        if (BOOST_UNLIKELY(!m_event))
+        {
+            const DWORD err = GetLastError();
+            BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to create Windows event", (err));
+        }
     }
 }
 
 //! Destructor
 BOOST_LOG_API winapi_based_event::~winapi_based_event()
 {
-    BOOST_VERIFY(CloseHandle(m_event) != 0);
+    if (!!m_event)
+    {
+        BOOST_VERIFY(CloseHandle(m_event) != 0);
+    }
 }
 
 //! Waits for the object to become signalled
 BOOST_LOG_API void winapi_based_event::wait()
 {
-    // On Windows we assume that memory view is always actual (Intel x86 and x86_64 arch)
-    if (const_cast< volatile boost::uint32_t& >(m_state) == 0)
+    if (!m_event)
     {
-        if (BOOST_UNLIKELY(WaitForSingleObject(m_event, INFINITE) != 0))
+        while (m_state.exchange(0u, boost::memory_order_acq_rel) == 0u)
         {
-            const DWORD err = GetLastError();
-            BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to block on Windows event", (err));
+            m_state.wait(0u, boost::memory_order_relaxed);
+        }
+    }
+    else
+    {
+        while (m_state.exchange(0u, boost::memory_order_acq_rel) == 0u)
+        {
+            if (BOOST_UNLIKELY(WaitForSingleObject(m_event, INFINITE) != 0))
+            {
+                const DWORD err = GetLastError();
+                BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to block on Windows event", (err));
+            }
         }
     }
-    const_cast< volatile boost::uint32_t& >(m_state) = 0;
 }
 
 //! Sets the object to a signalled state
 BOOST_LOG_API void winapi_based_event::set_signalled()
 {
-    if (BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast< long* >(&m_state), 1, 0) == 0)
+    if (m_state.load(boost::memory_order_relaxed) != 0u)
+    {
+        boost::atomic_thread_fence(boost::memory_order_release);
+    }
+    else if (m_state.exchange(1u, boost::memory_order_release) == 0u)
     {
-        if (BOOST_UNLIKELY(SetEvent(m_event) == 0))
+        if (!m_event)
         {
-            const DWORD err = GetLastError();
-            const_cast< volatile boost::uint32_t& >(m_state) = 0;
-            BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to wake the blocked thread", (err));
+            m_state.notify_one();
+        }
+        else
+        {
+            if (BOOST_UNLIKELY(SetEvent(m_event) == 0))
+            {
+                const DWORD err = GetLastError();
+                m_state.store(0u, boost::memory_order_relaxed);
+                BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to wake the blocked thread", (err));
+            }
         }
     }
 }