7 #include <cdsannotate.h>
8 #include <specannotation.h>
9 #include <model_memory.h>
16 template <typename t_element, size_t t_size>
17 struct mpmc_boundq_1_alt
23 atomic<t_element*> arr;
25 // elements should generally be cache-line-size padded :
26 t_element m_array[t_size];
28 // rdwr counts the reads & writes that have started
29 atomic<unsigned int> m_rdwr;
30 // "read" and "written" count the number completed
31 atomic<unsigned int> m_read;
32 atomic<unsigned int> m_written;
36 mpmc_boundq_1_alt(int _MASK = 0xFFFF)
46 // For this we want MASK = 1; MASK wrap around
56 CLASS = mpmc_boundq_1_alt;
61 @Commutativity: Prepare <-> Prepare: _Method1.__RET__ !=
62 _Method2.__RET__ || !_Method1.__RET__ || !_Method2.__RET__
63 @Commutativity: Prepare <-> Publish: _Method1.__RET__ != _Method2.bin ||
65 @Commutativity: Prepare <-> Fetch: _Method1.__RET__ != _Method2.__RET__
66 || !_Method1.__RET__ || !_Method2.__RET__
67 @Commutativity: Prepare <-> Consume : _Method1.__RET__ != _Method2.bin || !_Method1.__RET__
69 @Commutativity: Publish <-> Publish: _Method1.bin != _Method2.bin
70 @Commutativity: Publish <-> Fetch: _Method1.bin != _Method2.__RET__ ||
72 @Commutativity: Publish <-> Consume : _Method1.bin != _Method2.bin
74 @Commutativity: Fetch <-> Fetch: _Method1.__RET__ != _Method2.__RET__ ||
75 !_Method1.__RET__ || !_Method2.__RET__
76 @Commutativity: Fetch <-> Consume : _Method1.__RET__ != _Method2.bin || !_Method1.__RET__
78 @Commutativity: Consume <-> Consume : _Method1.bin != _Method2.bin
83 //-----------------------------------------------------
88 @Commit_point_set: FetchReadRW1 | FetchReadRW2 | FetchReadPointer
89 @ID: (call_id_t) __RET__
90 //@Action: model_print("Fetch: %d\n", __RET__);
93 t_element * read_fetch() {
94 // Since we have a lool to CAS the value of m_rdwr, this can be relaxed
95 unsigned int rdwr = m_rdwr.load(mo_acquire);
96 //unsigned int rdwr = m_rdwr.load(mo_relaxed);
99 @Commit_point_define_check: true
105 rd = (rdwr>>16) & MASK;
108 if ( wr == rd ) { // empty
111 /**** Inadmissibility (testcase2.cc, MASK = 1, size = 1) ****/
113 m_rdwr.compare_exchange_weak(rdwr,rdwr+(1<<16),mo_acq_rel);
119 @Commit_point_clear: true
126 @Commit_point_define_check: true
137 /**** Inadmissibility ****/
138 int written = m_written.load(mo_acquire);
139 if ((written & MASK) != wr) {
142 printf("Fetch: m_written=%d\n", written);
146 t_element * p = & ( m_array[ rd % t_size ] );
148 // This is just a hack to tell the CDSChecker that we have a memory
150 arr.load(memory_order_relaxed);
153 @Commit_point_clear: true
159 @Commit_point_define_check: true
160 @Label: FetchReadPointer
170 @Commit_point_set: ConsumeFetchAdd
172 //@Action: model_print("Consume: %d\n", bin);
175 void read_consume(t_element *bin) {
176 /**** Inadmissibility ****/
177 m_read.fetch_add(1,mo_release);
180 @Commit_point_define_check: true
181 @Label: ConsumeFetchAdd
186 //-----------------------------------------------------
191 @Commit_point_set: PrepareReadRW1 | PrepareReadRW2 | PrepareReadPointer
192 @ID: (call_id_t) __RET__
193 //@Action: model_print("Prepare: %d\n", __RET__);
196 t_element * write_prepare() {
197 // Try weaker semantics
198 // Since we have a lool to CAS the value of m_rdwr, this can be relaxed
199 unsigned int rdwr = m_rdwr.load(mo_acquire);
200 //unsigned int rdwr = m_rdwr.load(mo_relaxed);
203 @Commit_point_define_check: true
204 @Label: PrepareReadRW1
209 rd = (rdwr>>16) & MASK;
211 //printf("write_prepare: rd=%d, wr=%d\n", rd, wr);
213 if ( wr == ((rd + t_size)&MASK) ) { // full
217 /**** Inadmissibility (testcase3.cc, MASK = 1, size = 1) ****/
218 bool succ = m_rdwr.compare_exchange_weak(rdwr,(rd<<16) |
219 ((wr+1)&MASK),mo_acq_rel);
220 //printf("wr=%d\n", (wr+1)&MASK);
226 @Commit_point_clear: true
227 @Label: PrepareClear1
233 @Commit_point_define_check: true
234 @Label: PrepareReadRW2
244 /**** Inadmissibility ****/
245 int read = m_read.load(mo_acquire);
246 if ((read & MASK) != rd)
252 t_element * p = & ( m_array[ wr % t_size ] );
254 // This is also just a hack to tell the CDSChecker that we have a memory
256 arr.load(memory_order_relaxed);
259 @Commit_point_clear: true
260 @Label: PrepareClear2
265 @Commit_point_define_check: true
266 @Label: PrepareReadPointer
276 @Commit_point_set: Publish_W_RMW
278 //@Action: model_print("Publish: %d\n", bin);
281 void write_publish(t_element *bin)
283 /**** Inadmissibility ****/
284 int tmp = m_written.fetch_add(1,mo_release);
287 @Commit_point_define_check: true
288 @Label: Publish_W_RMW
291 printf("publish: m_written=%d\n", tmp + 1);
294 //-----------------------------------------------------