2019-06-06 07:40:04 +00:00
|
|
|
#ifndef UDPC_THREADSAFE_QUEUE_HPP
|
|
|
|
#define UDPC_THREADSAFE_QUEUE_HPP
|
|
|
|
|
|
|
|
#define UDPC_TSQUEUE_DEFAULT_CAPACITY 32
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <memory>
|
|
|
|
|
2019-07-07 05:13:16 +00:00
|
|
|
#include <RB/RingBuffer.hpp>
|
|
|
|
|
|
|
|
template <typename T>
|
2019-06-06 07:40:04 +00:00
|
|
|
class TSQueue {
|
|
|
|
public:
|
2019-07-07 05:13:16 +00:00
|
|
|
TSQueue(unsigned int capacity = UDPC_TSQUEUE_DEFAULT_CAPACITY);
|
2019-06-06 07:40:04 +00:00
|
|
|
~TSQueue();
|
|
|
|
|
|
|
|
// disable copy
|
|
|
|
TSQueue(const TSQueue &other) = delete;
|
|
|
|
TSQueue &operator=(const TSQueue &other) = delete;
|
|
|
|
// disable move
|
|
|
|
TSQueue(TSQueue &&other) = delete;
|
|
|
|
TSQueue &operator=(TSQueue &&other) = delete;
|
|
|
|
|
2019-07-07 05:13:16 +00:00
|
|
|
bool push(const T &data);
|
|
|
|
T top();
|
2019-06-06 07:40:04 +00:00
|
|
|
bool pop();
|
2019-06-06 08:06:44 +00:00
|
|
|
void clear();
|
|
|
|
void changeCapacity(unsigned int newCapacity);
|
|
|
|
unsigned int size();
|
2019-06-06 07:40:04 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
std::atomic_bool spinLock;
|
2019-07-07 05:13:16 +00:00
|
|
|
RB::RingBuffer<T> rb;
|
2019-06-06 07:40:04 +00:00
|
|
|
};
|
|
|
|
|
2019-07-07 05:13:16 +00:00
|
|
|
template <typename T>
|
|
|
|
TSQueue<T>::TSQueue(unsigned int capacity) :
|
|
|
|
spinLock(false),
|
|
|
|
rb(capacity)
|
|
|
|
{
|
|
|
|
rb.setResizePolicy(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
TSQueue<T>::~TSQueue()
|
|
|
|
{}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool TSQueue<T>::push(const T &data) {
|
|
|
|
while(spinLock.exchange(true)) {}
|
|
|
|
if(rb.getSize() == rb.getCapacity()) {
|
|
|
|
spinLock.store(false);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
rb.push(data);
|
|
|
|
spinLock.store(false);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T TSQueue<T>::top() {
|
|
|
|
while(spinLock.exchange(true)) {}
|
|
|
|
T value = rb.top();
|
|
|
|
spinLock.store(false);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool TSQueue<T>::pop() {
|
|
|
|
while(spinLock.exchange(true)) {}
|
|
|
|
if(rb.empty()) {
|
|
|
|
spinLock.store(false);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
rb.pop();
|
|
|
|
spinLock.store(false);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void TSQueue<T>::clear() {
|
|
|
|
while(spinLock.exchange(true)) {}
|
|
|
|
rb.resize(0);
|
|
|
|
spinLock.store(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void TSQueue<T>::changeCapacity(unsigned int newCapacity) {
|
|
|
|
while(spinLock.exchange(true)) {}
|
|
|
|
rb.changeCapacity(newCapacity);
|
|
|
|
spinLock.store(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
unsigned int TSQueue<T>::size() {
|
|
|
|
while(spinLock.exchange(true)) {}
|
|
|
|
unsigned int size = rb.getSize();
|
|
|
|
spinLock.store(false);
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2019-06-06 07:40:04 +00:00
|
|
|
#endif
|