edits
[cdsspec-compiler.git] / benchmark / mpmc-queue / mpmc-queue.h
index a1f5b1c2f40e17954217c4256ba4e04186f7fb96..aa1012976ee8501596d27cc7852f9006ea0e1e0c 100644 (file)
@@ -1,6 +1,18 @@
 #include <stdatomic.h>
 #include <unrelacy.h>
+#include <common.h>
 
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+
+/**
+       @Begin
+       @Class_begin
+       @End
+*/
 template <typename t_element, size_t t_size>
 struct mpmc_boundq_1_alt
 {
@@ -19,6 +31,11 @@ public:
 
        mpmc_boundq_1_alt()
        {
+       /**
+               @Begin
+                       @Entry_point
+                       @End
+               */
                m_rdwr = 0;
                m_read = 0;
                m_written = 0;
@@ -26,151 +43,31 @@ public:
        
 
        /**
-               @Global_define:
+               @Begin
                @Options:
                        LANG = CPP;
                        CLASS = mpmc_boundq_1_alt;
-               @DeclareStruct:
-                       typedef struct elem {
-                               t_element *pos;
-                               boolean written;
-                               thread_id_t tid;
-                               call_id_t id;
-                       } elem;
-               @DeclareVar:
-                       spec_list *list;
-                       id_tag_t *tag;
-               @InitVar:
-                       list = new_spec_list();
-                       tag = new_id_tag();
-               @DefineFunc:
-                       elem* new_elem(t_element *pos, call_id_t id, thread_id_t tid) {
-                               elem *e = (elem*) MODEL_MALLOC(sizeof(elem));
-                               e->pos = pos;
-                               e->written = false;
-                               e->id = id;
-                               e->tid = tid;
-                       }
-               @DefineFunc:
-                       elem* get_elem_by_pos(t_element *pos) {
-                               for (int i = 0; i < size(list); i++) {
-                                       elem *e = (elem*) elem_at_index(list, i);
-                                       if (e->pos == pos) {
-                                               return e;
-                                       }
-                               }
-                               return NULL;
-                       }
-               @DefineFunc:
-                       elem* get_elem_by_tid(thread_id_t tid) {
-                               for (int i = 0; i < size(list); i++) {
-                                       elem *e = (elem*) elem_at_index(list, i);
-                                       if (e->tid== tid) {
-                                               return e;
-                                       }
-                               }
-                               return NULL;
-                       }
-               @DefineFunc:
-                       int elem_idx_by_pos(t_element *pos) {
-                               for (int i = 0; i < size(list); i++) {
-                                       elem *existing = (elem*) elem_at_index(list, i);
-                                       if (pos == existing->pos) {
-                                               return i;
-                                       }
-                               }
-                               return -1;
-                       }
-               @DefineFunc:
-                       int elem_idx_by_tid(thread_id_t tid) {
-                               for (int i = 0; i < size(list); i++) {
-                                       elem *existing = (elem*) elem_at_index(list, i);
-                                       if (tid == existing->tid) {
-                                               return i;
-                                       }
-                               }
-                               return -1;
-                       }
-               @DefineFunc:
-                       call_id_t prepare_id() {
-                               return get_and_inc(tag);
-                       }
-               @DefineFunc:
-                       bool prepare_check(t_element *pos, thread_id_t tid) {
-                               elem *e = get_elem_by_tid(tid);
-                               return NULL == e;
-                       }
-               @DefineFunc:
-                       void prepare(call_id_t id, t_element *pos, thread_id_t tid) {
-                               call_id_t id = get_and_inc(tag);
-                               elem *e = new_elem(pos, id, tid);
-                               push_back(list, e);
-                       }
-               @DefineFunc:
-                       call_id_t publish_id(thread_id_t tid) {
-                               elem *e = get_elem_by_tid(tid);
-                               if (NULL == e)
-                                       return DEFAULT_CALL_ID;
-                               return e->id;
-                       }
-               @DefineFunc:
-                       bool publish_check(thread_id_t tid) {
-                               elem *e = get_elem_by_tid(tid);
-                               if (NULL == e)
-                                       return false;
-                               return e->written;
-                       }
-               @DefineFunc:
-                       void publish(thread_id_t tid) {
-                               elem *e = get_elem_by_tid(tid);
-                               e->written = true;
-                       }
-               @DefineFunc:
-                       call_id_t fetch_id(t_element *pos) {
-                               elem *e = get_elem_by_pos(pos);
-                               if (NULL == e)
-                                       return DEFAULT_CALL_ID;
-                               return e->id;
-                       }
-               @DefineFunc:
-                       bool fetch_check(t_element *pos) {
-                               int idx = elem_idx_by_pos(pos);
-                               if (idx == -1)
-                                       return false;
-                               else
-                                       return true;
-                       }
-               @DefineFunc:
-                       void fetch(t_element *pos) {
-                               int idx = elem_idx_by_pos(pos);
-                               if (idx == -1)
-                                       return;
-                               remove_at_index(list, idx);
-                       }
-               @DefineFunc:
-                       bool consume_check(thread_id_t tid) {
-                               elem *e = get_elem_by_tid(tid);
-                               if (NULL == e)
-                                       return false;
-                               return e->written;
-                       }
-               @DefineFunc:
-                       call_id_t consume_id(thread_id_t tid) {
-                               elem *e = get_elem_by_tid(tid);
-                               if (NULL == e)
-                                       return DEFAULT_CALL_ID;
-                               return e->id;
-                       }
-               @DefineFunc:
-                       void consume(thread_id_t tid) {
-                               int idx = elem_idx_by_tid(tid);
-                               if (idx == -1)
-                                       return;
-                               remove_at_index(list, idx);
-                       }
+               @Global_define:
+               //@DeclareStruct:
+                       //typedef struct elem {
+                       //      t_element *pos;
+                       //      bool written;
+                       //      thread_id_t tid;
+                       //      thread_id_t fetch_tid;
+                       //      call_id_t id;
+               //      } elem;
+       //      @DeclareVar:
+       //              spec_list *list;
+                       //id_tag_t *tag;
+       //      @InitVar:
+       //              list = new_spec_list();
+                       //tag = new_id_tag();
+       //      @Cleanup:
+//                     if (list)
+//                             free_spec_list();
        @Happens_before:
-               Prepare -> Fetch
-               Publish -> Consume
+               Publish -> Fetch
+               Consume -> Prepare
        @End
        */
 
@@ -179,26 +76,48 @@ public:
        /**
                @Begin
                @Interface: Fetch
-               @Commit_point_set: Fetch_Point
-               @ID: fetch_id(__RET__)
-               @Check:
-                       fetch_check(__RET__)
-               @Action:
-                       fetch(__RET__);
+               @Commit_point_set: Fetch_RW_Load_Empty | Fetch_RW_RMW | Fetch_W_Load
+               @ID: (call_id_t) __RET__
+               //@Check:
+                       //__RET__ == NULL || has_elem(list, __RET__)
                @End
        */
        t_element * read_fetch() {
+               // Try this new weaker semantics
                unsigned int rdwr = m_rdwr.load(mo_acquire);
+               //unsigned int rdwr = m_rdwr.load(mo_relaxed);
+               /**
+                       @Begin
+                       @Potential_commit_point_define: true
+                       @Label: Fetch_Potential_RW_Load
+                       @End
+               */
                unsigned int rd,wr;
                for(;;) {
                        rd = (rdwr>>16) & 0xFFFF;
                        wr = rdwr & 0xFFFF;
 
                        if ( wr == rd ) { // empty
+
+                               /**
+                                       @Begin
+                                       @Commit_point_define: true
+                                       @Potential_commit_point_label: Fetch_Potential_RW_Load
+                                       @Label: Fetch_RW_Load_Empty
+                                       @End
+                               */
+
                                return false;
                        }
-
-                       if ( m_rdwr.compare_exchange_weak(rdwr,rdwr+(1<<16),mo_acq_rel) )
+                       
+                       bool succ = m_rdwr.compare_exchange_weak(rdwr,rdwr+(1<<16),mo_acq_rel);
+                       /**
+                               @Begin
+                               @Commit_point_define_check: succ
+                               @Label: Fetch_RW_RMW
+                               @End
+                       */
+                       if (succ)
                                break;
                        else
                                thrd_yield();
@@ -206,9 +125,28 @@ public:
 
                // (*1)
                rl::backoff bo;
-               while ( (m_written.load(mo_acquire) & 0xFFFF) != wr ) {
-                       thrd_yield();
+               while (true) {
+                       int written = m_written.load(mo_acquire);
+                       /**
+                               @Begin
+                               @Potential_commit_point_define: true
+                               @Label: Fetch_Potential_W_Load
+                               @End
+                       */
+                       if ((written & 0xFFFF) != wr) {
+                               thrd_yield();
+                       } else {
+                               break;
+                       }
                }
+               
+               /**
+                       @Begin
+                       @Commit_point_define: true
+                       @Potential_commit_point_label: Fetch_Potential_W_Load
+                       @Label: Fetch_W_Load
+                       @End
+               */
 
                t_element * p = & ( m_array[ rd % t_size ] );
                
@@ -218,16 +156,23 @@ public:
        /**
                @Begin
                @Interface: Consume
-               @Commit_point_set: Consume_Point
-               @ID: consume_id(__TID__)
-               @Check:
-                       consume_check(__TID__)
-               @Action:
-                       consume(__TID__);
+               @Commit_point_set: Consume_R_RMW
+               @ID: (call_id_t) bin 
+               //@Check:
+               //      consume_check(__TID__)
+               //@Action:
+                       //consume(__TID__);
                @End
        */
-       void read_consume() {
+       void read_consume(t_element *bin) {
+               /**** FIXME: miss ****/
                m_read.fetch_add(1,mo_release);
+               /**
+                       @Begin
+                       @Commit_point_define_check: true
+                       @Label: Consume_R_RMW
+                       @End
+               */
        }
 
        //-----------------------------------------------------
@@ -235,25 +180,50 @@ public:
        /**
                @Begin
                @Interface: Prepare 
-               @Commit_point_set: Prepare_Point
-               @ID: prepare_id(__RET__)
-               @Check:
-                       prepare_check(__RET__)
-               @Action:
-                       prepare(__RET__);
+               @Commit_point_set: Prepare_RW_Load_Full | Prepare_RW_RMW | Prepare_R_Load
+               @ID: (call_id_t) __RET__
+               //@Check:
+                       //prepare_check(__RET__, __TID__)
+               //@Action:
+                       //push_back(list, __RET__);
                @End
        */
        t_element * write_prepare() {
+               // Try weaker semantics
                unsigned int rdwr = m_rdwr.load(mo_acquire);
+               //unsigned int rdwr = m_rdwr.load(mo_relaxed);
+               /**
+                       @Begin
+                       @Potential_commit_point_define: true
+                       @Label: Prepare_Potential_RW_Load
+                       @End
+               */
                unsigned int rd,wr;
                for(;;) {
                        rd = (rdwr>>16) & 0xFFFF;
                        wr = rdwr & 0xFFFF;
 
-                       if ( wr == ((rd + t_size)&0xFFFF) ) // full
-                               return NULL;
+                       if ( wr == ((rd + t_size)&0xFFFF) ) { // full
 
-                       if ( m_rdwr.compare_exchange_weak(rdwr,(rd<<16) | ((wr+1)&0xFFFF),mo_acq_rel) )
+                               /**
+                                       @Begin
+                                       @Commit_point_define: true
+                                       @Potential_commit_point_label: Prepare_Potential_RW_Load
+                                       @Label: Prepare_RW_Load_Full
+                                       @End
+                               */
+                               return NULL;
+                       }
+                       
+                       bool succ = m_rdwr.compare_exchange_weak(rdwr,(rd<<16) |
+                               ((wr+1)&0xFFFF),mo_acq_rel);
+                       /**
+                               @Begin
+                               @Commit_point_define_check: succ
+                               @Label: Prepare_RW_RMW
+                               @End
+                       */
+                       if (succ)
                                break;
                        else
                                thrd_yield();
@@ -261,10 +231,27 @@ public:
 
                // (*1)
                rl::backoff bo;
-               while ( (m_read.load(mo_acquire) & 0xFFFF) != rd ) {
-                       thrd_yield();
+               while (true) {
+                       int read = m_read.load(mo_acquire);
+                       /**
+                               @Begin
+                               @Potential_commit_point_define: true
+                               @Label: Prepare_Potential_R_Load
+                               @End
+                       */
+                       if ((read & 0xFFFF) != rd)
+                               thrd_yield();
+                       else
+                               break;
                }
 
+               /**
+                       @Begin
+                       @Commit_point_define: true
+                       @Potential_commit_point_label: Prepare_Potential_R_Load
+                       @Label: Prepare_R_Load
+                       @End
+               */
 
                t_element * p = & ( m_array[ wr % t_size ] );
 
@@ -274,20 +261,32 @@ public:
        /**
                @Begin
                @Interface: Publish 
-               @Commit_point_set: Publish_Point
-               @ID: publish_id(__TID__)
-               @Check:
-                       publish_check(__TID__)
-               @Action:
-                       publish(__TID__);
+               @Commit_point_set: Publish_W_RMW
+               @ID: (call_id_t) bin 
+               //@Check:
+                       //publish_check(__TID__)
+               //@Action:
+                       //publish(__TID__);
                @End
        */
-       void write_publish()
+       void write_publish(t_element *bin)
        {
+               /**** hb violation ****/
                m_written.fetch_add(1,mo_release);
+               /**
+                       @Begin
+                       @Commit_point_define_check: true
+                       @Label: Publish_W_RMW
+                       @End
+               */
        }
 
        //-----------------------------------------------------
 
 
 };
+/**
+       @Begin
+       @Class_end
+       @End
+*/