1 #ifndef _DETHREADSAFERINGBUFFER_HPP
2 #define _DETHREADSAFERINGBUFFER_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements C++ Base Library
5 * -----------------------------
7 * Copyright 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Thread-safe ring buffer template.
24 *//*--------------------------------------------------------------------*/
27 #include "deMutex.hpp"
28 #include "deSemaphore.hpp"
35 void ThreadSafeRingBuffer_selfTest (void);
37 /** Thread-safe ring buffer template. */
39 class ThreadSafeRingBuffer
42 ThreadSafeRingBuffer (size_t size);
43 ~ThreadSafeRingBuffer (void) {}
45 void pushFront (const T& elem);
46 bool tryPushFront (const T& elem);
48 bool tryPopBack (T& dst);
51 void pushFrontInternal (const T& elem);
52 T popBackInternal (void);
55 std::vector<T> m_elements;
67 // ThreadSafeRingBuffer implementation.
70 ThreadSafeRingBuffer<T>::ThreadSafeRingBuffer (size_t size)
78 // Semaphores currently only support INT_MAX
79 DE_ASSERT(size > 0 && size < 0x7fffffff);
83 inline void ThreadSafeRingBuffer<T>::pushFrontInternal (const T& elem)
85 m_elements[m_front] = elem;
86 m_front = (m_front + 1) % m_size;
90 inline T ThreadSafeRingBuffer<T>::popBackInternal ()
92 const size_t ndx = m_back;
93 m_back = (m_back + 1) % m_size;
94 return m_elements[ndx];
98 void ThreadSafeRingBuffer<T>::pushFront (const T& elem)
102 pushFrontInternal(elem);
104 m_writeMutex.unlock();
107 template <typename T>
108 bool ThreadSafeRingBuffer<T>::tryPushFront (const T& elem)
110 if (!m_writeMutex.tryLock())
113 const bool success = m_empty.tryDecrement();
117 pushFrontInternal(elem);
121 m_writeMutex.unlock();
125 template <typename T>
126 T ThreadSafeRingBuffer<T>::popBack ()
130 T elem = popBackInternal();
132 m_readMutex.unlock();
136 template <typename T>
137 bool ThreadSafeRingBuffer<T>::tryPopBack (T& dst)
139 if (!m_readMutex.tryLock())
142 bool success = m_fill.tryDecrement();
146 dst = popBackInternal();
150 m_readMutex.unlock();
157 #endif // _DETHREADSAFERINGBUFFER_HPP