add "lock-free queue"
[model-checker-benchmarks.git] / queue / g_blocking_queue.h
1 // ============================================================================
2 // Copyright (c) 2009-2010 Faustino Frechilla
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 //  1. Redistributions of source code must retain the above copyright notice,
9 //     this list of conditions and the following disclaimer.
10 //  2. Redistributions in binary form must reproduce the above copyright
11 //     notice, this list of conditions and the following disclaimer in the
12 //     documentation and/or other materials provided with the distribution.
13 //  3. The name of the author may not be used to endorse or promote products
14 //     derived from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 // POSSIBILITY OF SUCH DAMAGE.
27 //
28 /// @file q_blocking_queue.h
29 /// @brief Definition of a thread-safe queue based on glib system calls
30 /// It internally contains a std::queue which is protected from concurrent
31 /// access by glib mutextes and conditional variables
32 ///
33 /// @author Faustino Frechilla
34 /// @history
35 /// Ref  Who                 When         What
36 ///      Faustino Frechilla 04-May-2009 Original development (based on pthreads)
37 ///      Faustino Frechilla 19-May-2010 Ported to glib. Removed pthread dependency
38 /// @endhistory
39 ///
40 // ============================================================================
41
42 #ifndef _GBLOCKINGQUEUE_H_
43 #define _GBLOCKINGQUEUE_H_
44
45 #include <glib.h>
46 #include <queue>
47 #include <limits> // std::numeric_limits<>::max
48
49 #define BLOCKING_QUEUE_DEFAULT_MAX_SIZE std::numeric_limits<std::size_t >::max()
50
51 /// @brief blocking thread-safe queue
52 /// It uses a mutex+condition variables to protect the internal queue
53 /// implementation. Inserting or reading elements use the same mutex
54 template <typename T>
55 class BlockingQueue
56 {
57 public:
58     BlockingQueue(std::size_t a_maxSize = BLOCKING_QUEUE_DEFAULT_MAX_SIZE);
59     ~BlockingQueue();
60
61     /// @brief Check if the queue is empty
62     /// This call can block if another thread owns the lock that protects the
63     /// queue
64     /// @return true if the queue is empty. False otherwise
65     bool IsEmpty();
66
67     /// @brief inserts an element into queue queue
68     /// This call can block if another thread owns the lock that protects the
69     /// queue. If the queue is full The thread will be blocked in this queue
70     /// until someone else gets an element from the queue
71     /// @param element to insert into the queue
72     /// @return True if the elem was successfully inserted into the queue.
73     ///         False otherwise
74     bool Push(const T &a_elem);
75
76     /// @brief inserts an element into queue queue
77     /// This call can block if another thread owns the lock that protects the
78     /// queue. If the queue is full The call will return false and the element
79     /// won't be inserted
80     /// @param element to insert into the queue
81     /// @return True if the elem was successfully inserted into the queue.
82     ///         False otherwise
83     bool TryPush(const T &a_elem);
84
85     /// @brief extracts an element from the queue (and deletes it from the q)
86     /// If the queue is empty this call will block the thread until there is
87     /// something in the queue to be extracted
88     /// @param a reference where the element from the queue will be saved to
89     void Pop(T &out_data);
90
91     /// @brief extracts an element from the queue (and deletes it from the q)
92     /// This call gets the block that protects the queue. It will extract the
93     /// element from the queue only if there are elements in it
94     /// @param reference to the variable where the result will be saved
95     /// @return True if the element was retrieved from the queue.
96     ///         False if the queue was empty
97     bool TryPop(T &out_data);
98
99     /// @brief extracts an element from the queue (and deletes it from the q)
100     /// If the queue is empty this call will block the thread until there
101     /// is something in the queue to be extracted or until the timer
102     /// (2nd parameter) expires
103     /// @param reference to the variable where the result will be saved
104     /// @param microsecondsto wait before returning if the queue was empty
105     /// @return True if the element was retrieved from the queue.
106     ///         False if the timeout was reached
107     bool TimedWaitPop(T &data, glong microsecs);
108
109 protected:
110     std::queue<T> m_theQueue;
111     /// maximum number of elements for the queue
112     std::size_t m_maximumSize;
113     /// Mutex to protect the queue
114     GMutex* m_mutex;
115     /// Conditional variable to wake up threads
116     GCond*  m_cond;
117 };
118
119 // include the implementation file
120 #include "g_blocking_queue_impl.h"
121
122 #endif /* _GBLOCKINGQUEUE_H_ */