Imported Upstream version 0.13.2+dsfg1
This commit is contained in:
commit
fb3990e9e5
2036 changed files with 287360 additions and 0 deletions
65
plugins/mac-avcapture/left-right.hpp
Normal file
65
plugins/mac-avcapture/left-right.hpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
// left_right based on
|
||||
// https://github.com/pramalhe/ConcurrencyFreaks/blob/master/papers/left-right-2014.pdf
|
||||
// see concurrencyfreaks.com
|
||||
|
||||
namespace left_right {
|
||||
|
||||
template <typename T>
|
||||
struct left_right {
|
||||
template <typename Func>
|
||||
void update(Func &&f)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(write_mutex);
|
||||
auto cur = current.load();
|
||||
auto next = (cur + 1) & 1;
|
||||
|
||||
while (readers[next] != 0)
|
||||
std::this_thread::yield();
|
||||
|
||||
f(data[next]);
|
||||
current = next;
|
||||
|
||||
while (readers[cur] != 0)
|
||||
std::this_thread::yield();
|
||||
|
||||
f(data[cur]);
|
||||
}
|
||||
|
||||
T read()
|
||||
{
|
||||
auto cur = current.load();
|
||||
for (;;) {
|
||||
readers[cur] += 1;
|
||||
|
||||
auto cur_ = current.load();
|
||||
if (cur_ == cur)
|
||||
break;
|
||||
|
||||
readers[cur] -= 1;
|
||||
cur = cur_;
|
||||
}
|
||||
|
||||
auto val = data[cur];
|
||||
|
||||
readers[cur] -= 1;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic_uint_fast8_t current;
|
||||
std::atomic_long readers[2];
|
||||
std::mutex write_mutex;
|
||||
|
||||
T data[2] = {{}, {}};
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue