OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
triple_buffer.hpp
1#pragma once
2#include <atomic>
3
4namespace ossia
5{
6
7template <typename T>
8class triple_buffer
9{
10 T data[3] = {};
11
12 std::atomic<T*> to_read{&data[0]};
13 std::atomic<T*> buffer{&data[1]};
14 std::atomic<T*> to_write{&data[2]};
15
16 std::atomic_flag stale;
17
18public:
19 explicit triple_buffer(T init)
20 {
21 // Store the initial data in the "ready" buffer:
22 data[1] = std::move(init);
23 data[0] = data[1];
24 data[2] = data[1];
25 stale.clear();
26 }
27
28 void produce(T& t)
29 {
30 using namespace std;
31
32 // Load the data in the buffer
33 auto& old = *to_write.load();
34 swap(old, t);
35
36 // Perform the buffer swap: ready <-> to_write
37 auto p = buffer.exchange(to_write);
38 to_write.store(p);
39
40 // Notify the reader that new data is available
41 stale.clear();
42 }
43
44 bool consume(T& res)
45 {
46 using namespace std;
47
48 // Check if new data is available
49 if(stale.test_and_set())
50 return false;
51
52 // Load the new data: ready <-> present:
53 auto p = buffer.exchange(to_read);
54 to_read.store(p);
55
56 // Read back into our data
57 swap(res, *p);
58 return true;
59 }
60
61 auto& get_data() noexcept { return this->data; }
62};
63
64}
Definition git_info.h:7