summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/pmulti_threading.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/pmulti_threading.h')
-rw-r--r--src/lib/netlist/plib/pmulti_threading.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/lib/netlist/plib/pmulti_threading.h b/src/lib/netlist/plib/pmulti_threading.h
new file mode 100644
index 00000000000..f7b89079bc0
--- /dev/null
+++ b/src/lib/netlist/plib/pmulti_threading.h
@@ -0,0 +1,89 @@
+// license:BSD-3-Clause
+// copyright-holders:Couriersud
+
+#ifndef PMULTI_THREADING_H_
+#define PMULTI_THREADING_H_
+
+///
+/// \file pmulti_threading.h
+///
+
+#include "pconfig.h"
+
+#include <algorithm>
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+#include <type_traits>
+#include <utility>
+
+namespace plib {
+
+ template<bool enabled_ = true>
+ struct pspin_mutex
+ {
+ public:
+ inline pspin_mutex() noexcept = default;
+ inline void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } }
+ inline void unlock() noexcept { m_lock.clear(std::memory_order_release); }
+ private:
+ PALIGNAS_CACHELINE()
+ std::atomic_flag m_lock = ATOMIC_FLAG_INIT;
+ };
+
+ template<>
+ struct pspin_mutex<false>
+ {
+ public:
+ inline pspin_mutex() noexcept = default;
+ static inline void lock() noexcept { }
+ static inline void unlock() noexcept { }
+ };
+
+ class psemaphore
+ {
+ public:
+
+ psemaphore(long count = 0) noexcept: m_count(count) { }
+
+ psemaphore(const psemaphore& other) = delete;
+ psemaphore& operator=(const psemaphore& other) = delete;
+ psemaphore(psemaphore&& other) = delete;
+ psemaphore& operator=(psemaphore&& other) = delete;
+ ~psemaphore() = default;
+
+ void release(long update = 1)
+ {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ m_count += update;
+ m_cv.notify_one();
+ }
+
+ void acquire()
+ {
+ std::unique_lock<std::mutex> lock(m_mutex);
+ while (m_count == 0)
+ m_cv.wait(lock);
+ --m_count;
+ }
+
+ bool try_acquire()
+ {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ if (m_count)
+ {
+ --m_count;
+ return true;
+ }
+ return false;
+ }
+ private:
+ std::mutex m_mutex;
+ std::condition_variable m_cv;
+ long m_count;
+ };
+
+
+} // namespace plib
+
+#endif // PMULTI_THREADING_H_