libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
anon_spin_event.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_CORE_ANON_SPIN_EVENT_HPP
2 #define LIBJMMCG_CORE_ANON_SPIN_EVENT_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2014 by J.M.McGuiness, coder@hussar.me.uk
6 **
7 ** This library is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU Lesser General Public
9 ** License as published by the Free Software Foundation; either
10 ** version 2.1 of the License, or (at your option) any later version.
11 **
12 ** This library is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** Lesser General Public License for more details.
16 **
17 ** You should have received a copy of the GNU Lesser General Public
18 ** License along with this library; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
22 #include <atomic>
23 #include <thread>
24 
25 // TODO: see comment in "anon_spin_event::set()": #include <emmintrin.h>
26 
27 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace ppd { namespace lock {
28 
29 /// A very simple, atomic, lock-free mutex that is implemented with a busy-wait.
30 /**
31  Compare to the Win32 Critical Section object or futex. This is not ideal for heavily contended locks.
32  Moreover some platforms do not provide kernel objects such as mutexes, so one needs this to "bootsrap" protecting shared data structures in a nicer manner,
33 
34  c.f. <a href=" https://github.com/facebook/folly/blob/master/folly/synchronization/MicroSpinLock.h">folly::MicroSpinLock</a>. Also read the important notes in "man pthread_spin_init".
35  \see
36 */
37 template<class LkT>
38 class anon_spin_event final : public lock::lockable_settable<LkT> {
39 public:
40  using base_t=lock::lockable_settable<LkT>;
41  using lock_traits=typename base_t::lock_traits;
42  using atomic_state_type=typename lock_traits::atomic_state_type;
43  using lock_result_type=atomic_state_type;
44  using timeout_type=typename lock_traits::timeout_type;
45  using count_type=int;
46  using lock_type=lock::template in_process<anon_spin_event>;
47  using read_lock_type=lock_type;
48  using write_lock_type=lock_type;
49  using atomic_t=std::atomic_flag;
50 
51  /**
52  To assist in allowing compile-time computation of the algorithmic order of the threading model.
53  */
55 
56  /**
57  Initialise as "atom_unset".
58  */
59  __fastcall REALLY_FORCE_INLINE anon_spin_event() noexcept(true);
60  explicit __fastcall REALLY_FORCE_INLINE anon_spin_event(const atomic_state_type state) noexcept(true);
61  anon_spin_event(anon_spin_event const &)=delete;
62  anon_spin_event &operator=(anon_spin_event const &)=delete;
63 
64  atomic_state_type __fastcall REALLY_FORCE_INLINE set() noexcept(true) override;
65  lock_result_type __fastcall REALLY_FORCE_INLINE unlock() noexcept(true) override;
66  atomic_state_type __fastcall REALLY_FORCE_INLINE reset() noexcept(true) override;
67  lock_result_type __fastcall REALLY_FORCE_INLINE lock() noexcept(true) override;
68  lock_result_type __fastcall REALLY_FORCE_INLINE lock(const timeout_type) noexcept(true) override;
69 
70 private:
71  atomic_t state=ATOMIC_FLAG_INIT;
72 };
73 
74 } } } }
75 
77 
78 #endif