examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

triple-buf.cpp (1764B)


      1 #include <array>
      2 #include <atomic>
      3 #include <iostream>
      4 
      5 enum states
      6 {
      7 	wro,
      8 	wrn,
      9 	rwo,
     10 	rwn,
     11 
     12 	wor,
     13 	wnr,
     14 	row,
     15 	rnw,
     16 
     17 	owr,
     18 	nwr,
     19 	orw,
     20 	nrw,
     21 };
     22 
     23 struct state_table
     24 {
     25 	enum states push_next, pull_next;
     26 	unsigned char in, out;
     27 };
     28 
     29 constexpr struct state_table table[] =
     30 {
     31 	[wro] = {nrw, wro, 0, 1},
     32 	[wrn] = {nrw, wor, 0, 1},
     33 	[rwo] = {rnw, rwo, 1, 0},
     34 	[rwn] = {rnw, owr, 1, 0},
     35 	[wor] = {nwr, wor, 0, 2},
     36 	[wnr] = {nwr, wro, 0, 2},
     37 	[row] = {rwn, row, 2, 0},
     38 	[rnw] = {rwn, orw, 2, 0},
     39 	[owr] = {wnr, owr, 1, 2},
     40 	[nwr] = {wnr, rwo, 1, 2},
     41 	[orw] = {wrn, orw, 2, 1},
     42 	[nrw] = {wrn, row, 2, 1},
     43 };
     44 
     45 template <typename T>
     46 struct triple_buffer
     47 {
     48 	std::array<T, 3> bufs;
     49 	std::atomic<enum states> state;
     50 
     51 	T& get_write()
     52 	{
     53 		return bufs[table[state].in];
     54 	}
     55 
     56 	T& get_read()
     57 	{
     58 		return bufs[table[state].out];
     59 	}
     60 
     61 	void push(void)
     62 	{
     63 		enum states desired, expected = state;
     64 		do
     65 		{
     66 			desired = table[expected].push_next;
     67 
     68 		} while (not state.compare_exchange_strong(expected, desired, std::memory_order::seq_cst, std::memory_order::seq_cst));
     69 	}
     70 
     71 	bool pull(void)
     72 	{
     73 		enum states desired, expected = state;
     74 		do
     75 		{
     76 			desired = table[expected].pull_next;
     77 
     78 			if (desired == expected)
     79 				return false;
     80 
     81 		} while (not state.compare_exchange_strong(expected, desired, std::memory_order::seq_cst, std::memory_order::seq_cst));
     82 
     83 		return true;
     84 	}
     85 };
     86 
     87 
     88 int main(void)
     89 {
     90 	triple_buffer<int> b;
     91 
     92 	b.get_write() = 5;
     93 	b.push();
     94 
     95 	b.pull();
     96 	std::cout << b.get_read() << '\n';
     97 	b.pull();
     98 	std::cout << b.get_read() << '\n';
     99 
    100 	b.get_write() = 6;
    101 	b.push();
    102 
    103 	b.get_write() = 7;
    104 	b.push();
    105 
    106 	std::cout << b.get_read() << '\n';
    107 	b.pull();
    108 	std::cout << b.get_read() << '\n';
    109 
    110 	b.get_write() = 8;
    111 	b.push();
    112 
    113 	b.pull();
    114 	std::cout << b.get_read() << '\n';
    115 
    116 	return 0;
    117 }