1 template <typename t_element, size_t t_size>
2 struct mpmc_boundq_1_alt
6 // elements should generally be cache-line-size padded :
7 nonatomic<t_element> m_array[t_size];
9 // rdwr counts the reads & writes that have started
10 atomic<unsigned int> m_rdwr;
11 // "read" and "written" count the number completed
12 atomic<unsigned int> m_read;
13 atomic<unsigned int> m_written;
17 mpmc_boundq_1_alt() : m_rdwr(0), m_read(0), m_written(0)
21 //-----------------------------------------------------
23 nonatomic<t_element> * read_fetch() {
24 unsigned int rdwr = m_rdwr($).load(mo_acquire);
27 rd = (rdwr>>16) & 0xFFFF;
30 if ( wr == rd ) // empty
33 if ( m_rdwr($).compare_exchange_weak(rdwr,rdwr+(1<<16),mo_acq_rel) )
39 while ( (m_written($).load(mo_acquire) & 0xFFFF) != wr ) {
43 nonatomic<t_element> * p = & ( m_array[ rd % t_size ] );
49 m_read($).fetch_add(1,mo_release);
52 //-----------------------------------------------------
54 nonatomic<t_element> * write_prepare() {
55 unsigned int rdwr = m_rdwr($).load(mo_acquire);
58 rd = (rdwr>>16) & 0xFFFF;
61 if ( wr == ((rd + t_size)&0xFFFF) ) // full
64 if ( m_rdwr($).compare_exchange_weak(rdwr,(rd<<16) | ((wr+1)&0xFFFF),mo_acq_rel) )
70 while ( (m_read($).load(mo_acquire) & 0xFFFF) != rd ) {
74 nonatomic<t_element> * p = & ( m_array[ wr % t_size ] );
81 m_written($).fetch_add(1,mo_release);
84 //-----------------------------------------------------