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 > class LFQueue : public boost::noncopyable
43 : {
44 : public:
45 : /** Construct a new queue. @version 1.0 */
46 1 : explicit LFQueue( const int32_t size )
47 1 : : _data( size + 1 ), _readPos( 0 ), _writePos( 0 ) {}
48 :
49 : /** Destruct this queue. @version 1.0 */
50 0 : ~LFQueue() {}
51 :
52 : /** @return true if the queue is empty, false otherwise. @version 1.0 */
53 : bool isEmpty() const { return _readPos == _writePos; }
54 :
55 : /** Reset (empty) the queue. @version 1.0 */
56 : void clear();
57 :
58 : /**
59 : * Resize and reset the queue.
60 : *
61 : * This method is not thread-safe. The queue has to be empty.
62 : * @version 1.0
63 : */
64 : void resize( const int32_t size );
65 :
66 : /**
67 : * Retrieve and pop the front element from the queue.
68 : *
69 : * @param result the front value or unmodified
70 : * @return true if an element was placed in result, false if the queue
71 : * is empty.
72 : * @version 1.0
73 : */
74 : bool pop( T& result );
75 :
76 : /**
77 : * Retrieve the front element from the queue.
78 : *
79 : * @param result the front value or unmodified
80 : * @return true if an element was placed in result, false if the queue
81 : * is empty.
82 : * @version 1.0
83 : */
84 : bool getFront( T& result );
85 :
86 : /**
87 : * Push a new element to the back of the queue.
88 : *
89 : * @param element the element to add.
90 : * @return true if the element was placed, false if the queue is full
91 : * @version 1.0
92 : */
93 : bool push( const T& element );
94 :
95 : /**
96 : * @return the maximum number of elements held by the queue.
97 : * @version 1.0
98 : */
99 : size_t getCapacity() const { return _data.size() - 1; }
100 :
101 : private:
102 : std::vector< T > _data;
103 : a_int32_t _readPos;
104 : a_int32_t _writePos;
105 :
106 1 : LB_TS_VAR( _reader );
107 1 : LB_TS_VAR( _writer );
108 : };
109 : }
110 :
111 : #include "lfQueue.ipp" // template implementation
112 :
113 : #endif // LUNCHBOX_LFQUEUE_H
|