Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More Spin locks experiments #715

Merged
merged 1 commit into from
Mar 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/util/SpinMutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#pragma once
#include <atomic>

// A non-recursive Mutex implemented as a spin-lock.
// A non-recursive Mutex implemented as a spin-lock, implementing the Lockable requirement
class SpinMutex {

public:
Expand All @@ -18,6 +18,8 @@ class SpinMutex {

void lock() { while (lock_state.test_and_set(std::memory_order_acquire)); }

bool try_lock() {return !lock_state.test_and_set(std::memory_order_acquire); }

void unlock() { lock_state.clear(std::memory_order_release); }

private:
Expand Down
27 changes: 14 additions & 13 deletions src/util/ThreadBlockingQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <condition_variable>
#include <typeinfo>
#include <iostream>
#include "SpinMutex.h"

#define MIN_ITEM_NB (1)

Expand Down Expand Up @@ -50,7 +51,7 @@ class ThreadBlockingQueue : public ThreadQueueBase {

/*! Destroy safe queue. */
~ThreadBlockingQueue() {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
}

/**
Expand All @@ -59,7 +60,7 @@ class ThreadBlockingQueue : public ThreadQueueBase {
* \param[in] nb max of items
*/
void set_max_num_items(unsigned int max_num_items) {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);

if (max_num_items > m_max_num_items) {
//Only raise the existing max size, never reduce it
Expand All @@ -79,7 +80,7 @@ class ThreadBlockingQueue : public ThreadQueueBase {
* \return true if an item was pushed into the queue, else a timeout has occured.
*/
bool push(const value_type& item, std::uint64_t timeout = BLOCKING_INFINITE_TIMEOUT,const char* errorMessage = nullptr) {
std::unique_lock < std::mutex > lock(m_mutex);
std::unique_lock < SpinMutex > lock(m_mutex);

if (timeout == BLOCKING_INFINITE_TIMEOUT) {
m_cond_not_full.wait(lock, [this]() // Lambda funct
Expand Down Expand Up @@ -113,7 +114,7 @@ class ThreadBlockingQueue : public ThreadQueueBase {
* \param[in] item An item.
*/
bool try_push(const value_type& item) {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);

if (m_queue.size() >= m_max_num_items) {
return false;
Expand All @@ -131,7 +132,7 @@ class ThreadBlockingQueue : public ThreadQueueBase {
* \return true if get an item from the queue, false if no item is received before the timeout.
*/
bool pop(value_type& item, std::uint64_t timeout = BLOCKING_INFINITE_TIMEOUT, const char* errorMessage = nullptr) {
std::unique_lock < std::mutex > lock(m_mutex);
std::unique_lock < SpinMutex > lock(m_mutex);

if (timeout == BLOCKING_INFINITE_TIMEOUT) {
m_cond_not_empty.wait(lock, [this]() // Lambda funct
Expand Down Expand Up @@ -166,7 +167,7 @@ class ThreadBlockingQueue : public ThreadQueueBase {
* \return False is returned if no item is available.
*/
bool try_pop(value_type& item) {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);

if (m_queue.empty()) {
return false;
Expand All @@ -184,7 +185,7 @@ class ThreadBlockingQueue : public ThreadQueueBase {
* \return Number of items in the queue.
*/
size_type size() const {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
return m_queue.size();
}

Expand All @@ -193,7 +194,7 @@ class ThreadBlockingQueue : public ThreadQueueBase {
* \return true if queue is empty.
*/
bool empty() const {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
return m_queue.empty();
}

Expand All @@ -202,15 +203,15 @@ class ThreadBlockingQueue : public ThreadQueueBase {
* \return true if queue is full.
*/
bool full() const {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
return (m_queue.size() >= m_max_num_items);
}

/**
* Remove any items in the queue.
*/
void flush() {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
m_queue.clear();
m_cond_not_full.notify_all();
}
Expand All @@ -221,8 +222,8 @@ class ThreadBlockingQueue : public ThreadQueueBase {

std::deque<T> m_queue;

mutable std::mutex m_mutex;
std::condition_variable m_cond_not_empty;
std::condition_variable m_cond_not_full;
mutable SpinMutex m_mutex;
std::condition_variable_any m_cond_not_empty;
std::condition_variable_any m_cond_not_full;
size_t m_max_num_items = MIN_ITEM_NB;
};
6 changes: 3 additions & 3 deletions src/visual/WaterfallCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void WaterfallCanvas::attachSpectrumCanvas(SpectrumCanvas *canvas_in) {
}

void WaterfallCanvas::processInputQueue() {
std::lock_guard < SpinMutex > lock(tex_update);
std::lock_guard < std::mutex > lock(tex_update);

gTimer.update();

Expand Down Expand Up @@ -127,7 +127,7 @@ void WaterfallCanvas::processInputQueue() {
}

void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
std::lock_guard < SpinMutex > lock(tex_update);
std::lock_guard < std::mutex > lock(tex_update);
wxPaintDC dc(this);

const wxSize ClientSize = GetClientSize();
Expand Down Expand Up @@ -913,7 +913,7 @@ void WaterfallCanvas::updateCenterFrequency(long long freq) {
}

void WaterfallCanvas::setLinesPerSecond(int lps) {
std::lock_guard < SpinMutex > lock(tex_update);
std::lock_guard < std::mutex > lock(tex_update);

linesPerSecond = lps;

Expand Down
3 changes: 1 addition & 2 deletions src/visual/WaterfallCanvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "SpectrumCanvas.h"
#include "WaterfallPanel.h"
#include "Timer.h"
#include "SpinMutex.h"

class WaterfallCanvas: public InteractiveCanvas {
public:
Expand Down Expand Up @@ -94,7 +93,7 @@ class WaterfallCanvas: public InteractiveCanvas {
Timer gTimer;
double lpsIndex;
bool preBuf;
SpinMutex tex_update;
std::mutex tex_update;
int minBandwidth;
std::atomic_bool fft_size_changed;
// event table
Expand Down