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