Line data Source code
1 :
2 : /* Copyright (c) 2010-2014, 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_LFQUEUE_H
19 : #define LUNCHBOX_LFQUEUE_H
20 :
21 : #include <lunchbox/atomic.h> // member
22 : #include <lunchbox/debug.h> // used in inline method
23 : #include <lunchbox/thread.h> // thread-safety checks
24 :
25 : #include <vector>
26 :
27 : namespace lunchbox
28 : {
29 : /**
30 : * A thread-safe, lock-free queue with non-blocking access.
31 : *
32 : * Typically used for caches and non-blocking communication between two threads.
33 : *
34 : * Current implementation constraints:
35 : * * One reader thread
36 : * * One writer thread
37 : * * Fixed maximum size (writes may fail)
38 : * * Not copyable
39 : *
40 : * Example: @include tests/lfQueue.cpp
41 : */
42 : template <typename T>
43 : class LFQueue : public boost::noncopyable
44 : {
45 : public:
46 : /** Construct a new queue. @version 1.0 */
47 1 : explicit LFQueue(const int32_t size)
48 1 : : _data(size + 1)
49 : , _readPos(0)
50 2 : , _writePos(0)
51 : {
52 1 : }
53 :
54 : /** Destruct this queue. @version 1.0 */
55 1 : ~LFQueue() {}
56 : /** @return true if the queue is empty, false otherwise. @version 1.0 */
57 : bool isEmpty() const { return _readPos == _writePos; }
58 : /** Reset (empty) the queue. @version 1.0 */
59 : void clear();
60 :
61 : /**
62 : * Resize and reset the queue.
63 : *
64 : * This method is not thread-safe. The queue has to be empty.
65 : * @version 1.0
66 : */
67 : void resize(const int32_t size);
68 :
69 : /**
70 : * Retrieve and pop the front element from the queue.
71 : *
72 : * @param result the front value or unmodified
73 : * @return true if an element was placed in result, false if the queue
74 : * is empty.
75 : * @version 1.0
76 : */
77 : bool pop(T& result);
78 :
79 : /**
80 : * Retrieve the front element from the queue.
81 : *
82 : * @param result the front value or unmodified
83 : * @return true if an element was placed in result, false if the queue
84 : * is empty.
85 : * @version 1.0
86 : */
87 : bool getFront(T& result);
88 :
89 : /**
90 : * Push a new element to the back of the queue.
91 : *
92 : * @param element the element to add.
93 : * @return true if the element was placed, false if the queue is full
94 : * @version 1.0
95 : */
96 : bool push(const T& element);
97 :
98 : /**
99 : * @return the maximum number of elements held by the queue.
100 : * @version 1.0
101 : */
102 : size_t getCapacity() const { return _data.size() - 1; }
103 : private:
104 : std::vector<T> _data;
105 : a_int32_t _readPos;
106 : a_int32_t _writePos;
107 :
108 2 : LB_TS_VAR(_reader);
109 2 : LB_TS_VAR(_writer);
110 : };
111 : }
112 :
113 : #include "lfQueue.ipp" // template implementation
114 :
115 : #endif // LUNCHBOX_LFQUEUE_H
|