Line data Source code
1 :
2 : /* Copyright (c) 2010-2017, Stefan Eilemann <eile@equalizergraphics.com>
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 2.1 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #ifndef LUNCHBOX_SPINLOCK_H
19 : #define LUNCHBOX_SPINLOCK_H
20 :
21 : #include <lunchbox/atomic.h> // member
22 : #include <lunchbox/thread.h> // used in inline method
23 :
24 : #include <memory>
25 :
26 : namespace lunchbox
27 : {
28 : /**
29 : * A fast lock for uncontended memory access.
30 : *
31 : * If Thread::yield() does not work, priority inversion is possible. If used as
32 : * a read-write lock, readers or writers will starve on high contention.
33 : *
34 : * @sa ScopedMutex
35 : *
36 : * Example: @include tests/perf/lock.cpp
37 : */
38 : class SpinLock : public boost::noncopyable
39 : {
40 : public:
41 : /** Construct a new lock. @version 1.0 */
42 : LUNCHBOX_API SpinLock();
43 :
44 : /** Destruct the lock. @version 1.0 */
45 : LUNCHBOX_API ~SpinLock();
46 :
47 : /** Acquire the lock exclusively. @version 1.0 */
48 : LUNCHBOX_API void set();
49 8047 : void lock() { set(); }
50 : /** Release an exclusive lock. @version 1.0 */
51 : LUNCHBOX_API void unset();
52 8044 : void unlock() { unset(); }
53 : /**
54 : * Attempt to acquire the lock exclusively.
55 : *
56 : * @return true if the lock was set, false if it was not set.
57 : * @version 1.0
58 : */
59 : LUNCHBOX_API bool trySet();
60 :
61 : /** Acquire the lock shared with other readers. @version 1.1.2 */
62 : LUNCHBOX_API void setRead();
63 0 : void lock_shared() { setRead(); }
64 : /** Release a shared read lock. @version 1.1.2 */
65 : LUNCHBOX_API void unsetRead();
66 0 : void unlock_shared() { unsetRead(); }
67 : /**
68 : * Attempt to acquire the lock shared with other readers.
69 : *
70 : * @return true if the lock was set, false if it was not set.
71 : * @version 1.1.2
72 : */
73 : LUNCHBOX_API bool trySetRead();
74 :
75 : /**
76 : * Test if the lock is set.
77 : *
78 : * @return true if the lock is set, false if it is not set.
79 : * @version 1.0
80 : */
81 : LUNCHBOX_API bool isSet();
82 :
83 : /**
84 : * Test if the lock is set exclusively.
85 : *
86 : * @return true if the lock is set, false if it is not set.
87 : * @version 1.1.2
88 : */
89 : LUNCHBOX_API bool isSetWrite();
90 :
91 : /**
92 : * Test if the lock is set shared.
93 : *
94 : * @return true if the lock is set, false if it is not set.
95 : * @version 1.1.2
96 : */
97 : LUNCHBOX_API bool isSetRead();
98 :
99 : private:
100 : class Impl;
101 : std::unique_ptr<Impl> _impl;
102 :
103 : SpinLock(const SpinLock&) = delete;
104 : SpinLock(SpinLock&&) = delete;
105 : SpinLock& operator=(const SpinLock&) = delete;
106 : SpinLock& operator=(SpinLock&&) = delete;
107 : };
108 : }
109 : #endif // LUNCHBOX_SPINLOCK_H
|