wait_ops_dragonfly_umtx.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * Copyright (c) 2020 Andrey Semashev
  7. */
  8. /*!
  9. * \file atomic/detail/wait_ops_dragonfly_umtx.hpp
  10. *
  11. * This header contains implementation of the waiting/notifying atomic operations based on DragonFly BSD umtx.
  12. * https://man.dragonflybsd.org/?command=umtx&section=2
  13. */
  14. #ifndef BOOST_ATOMIC_DETAIL_WAIT_OPS_DRAGONFLY_UMTX_HPP_INCLUDED_
  15. #define BOOST_ATOMIC_DETAIL_WAIT_OPS_DRAGONFLY_UMTX_HPP_INCLUDED_
  16. #include <unistd.h>
  17. #include <boost/memory_order.hpp>
  18. #include <boost/atomic/detail/config.hpp>
  19. #include <boost/atomic/detail/wait_operations_fwd.hpp>
  20. #include <boost/atomic/detail/header.hpp>
  21. #ifdef BOOST_HAS_PRAGMA_ONCE
  22. #pragma once
  23. #endif
  24. namespace boost {
  25. namespace atomics {
  26. namespace detail {
  27. template< typename Base, bool Interprocess >
  28. struct wait_operations< Base, sizeof(int), true, Interprocess > :
  29. public Base
  30. {
  31. typedef Base base_type;
  32. typedef typename base_type::storage_type storage_type;
  33. static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = true;
  34. static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
  35. {
  36. return true;
  37. }
  38. static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
  39. {
  40. storage_type new_val = base_type::load(storage, order);
  41. while (new_val == old_val)
  42. {
  43. ::umtx_sleep(reinterpret_cast< int* >(const_cast< storage_type* >(&storage)), static_cast< int >(old_val), 0);
  44. new_val = base_type::load(storage, order);
  45. }
  46. return new_val;
  47. }
  48. static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) BOOST_NOEXCEPT
  49. {
  50. ::umtx_wakeup(reinterpret_cast< int* >(const_cast< storage_type* >(&storage)), 1);
  51. }
  52. static BOOST_FORCEINLINE void notify_all(storage_type volatile& storage) BOOST_NOEXCEPT
  53. {
  54. ::umtx_wakeup(reinterpret_cast< int* >(const_cast< storage_type* >(&storage)), 0);
  55. }
  56. };
  57. } // namespace detail
  58. } // namespace atomics
  59. } // namespace boost
  60. #include <boost/atomic/detail/footer.hpp>
  61. #endif // BOOST_ATOMIC_DETAIL_WAIT_OPS_DRAGONFLY_UMTX_HPP_INCLUDED_