optimizations to mpmc-queue yield placement
authorBrian Demsky <bdemsky@uci.edu>
Thu, 14 Mar 2013 07:24:25 +0000 (00:24 -0700)
committerBrian Demsky <bdemsky@uci.edu>
Thu, 14 Mar 2013 07:24:25 +0000 (00:24 -0700)
simpler test case for concurrent readers/writers of mpmc-queue

bench.sh
mpmc-queue/Makefile
mpmc-queue/mpmc-queue.cc
mpmc-queue/mpmc-queue.h

index 94d041fb401f6174a3e9d6dde47cda1a130c0510..88f114b1004b1f770bea67f6071f1db120d7f58d 100755 (executable)
--- a/bench.sh
+++ b/bench.sh
@@ -23,6 +23,8 @@ TESTS+=" spsc-bugfix/spsc-queue"
 TESTS+=" dekker-fences/dekker-fences"
 TESTS+=" mpmc-queue/mpmc-2r1w"
 TESTS+=" mpmc-queue/mpmc-1r2w-noinit"
+TESTS+=" mpmc-queue/mpmc-queue-rdwr"
+TESTS+=" mpmc-queue/mpmc-rdwr-noinit"
 TESTS+=" mpmc-queue/mpmc-queue-noinit"
 TESTS+=" linuxrwlocks/linuxrwlocks"
 
index 472b7946ce29ee64a2cd46aebf1765904eb62d16..cfd4fee04c49fb1ca2cc38b82d78c53b31464da5 100644 (file)
@@ -1,17 +1,19 @@
 include ../benchmarks.mk
 
 TESTNAME = mpmc-queue
-TESTS = mpmc-queue mpmc-1r2w mpmc-2r1w
-TESTS += mpmc-queue-noinit mpmc-1r2w-noinit mpmc-2r1w-noinit
+TESTS = mpmc-queue mpmc-1r2w mpmc-2r1w mpmc-queue-rdwr
+TESTS += mpmc-queue-noinit mpmc-1r2w-noinit mpmc-2r1w-noinit mpmc-rdwr-noinit
 
 all: $(TESTS)
 
 mpmc-queue: CPPFLAGS += -DCONFIG_MPMC_READERS=2 -DCONFIG_MPMC_WRITERS=2
+mpmc-queue-rdwr: CPPFLAGS += -DCONFIG_MPMC_READERS=0 -DCONFIG_MPMC_WRITERS=0 -DCONFIG_MPMC_RDWR=2
 mpmc-1r2w: CPPFLAGS += -DCONFIG_MPMC_READERS=1 -DCONFIG_MPMC_WRITERS=2
 mpmc-2r1w: CPPFLAGS += -DCONFIG_MPMC_READERS=2 -DCONFIG_MPMC_WRITERS=1
 mpmc-queue-noinit: CPPFLAGS += -DCONFIG_MPMC_READERS=2 -DCONFIG_MPMC_WRITERS=2 -DCONFIG_MPMC_NO_INITIAL_ELEMENT
 mpmc-1r2w-noinit: CPPFLAGS += -DCONFIG_MPMC_READERS=1 -DCONFIG_MPMC_WRITERS=2 -DCONFIG_MPMC_NO_INITIAL_ELEMENT
 mpmc-2r1w-noinit: CPPFLAGS += -DCONFIG_MPMC_READERS=2 -DCONFIG_MPMC_WRITERS=1 -DCONFIG_MPMC_NO_INITIAL_ELEMENT
+mpmc-rdwr-noinit: CPPFLAGS += -DCONFIG_MPMC_READERS=0 -DCONFIG_MPMC_WRITERS=0 -DCONFIG_MPMC_RDWR=2 -DCONFIG_MPMC_NO_INITIAL_ELEMENT
 
 $(TESTS): $(TESTNAME).cc $(TESTNAME).h
        $(CXX) -o $@ $< $(CPPFLAGS) $(LDFLAGS)
index baca598bfa49b39e70134672f12e67b9135a95f5..b62d8d31f496bce7a686332aad23ef7140e56653 100644 (file)
@@ -24,8 +24,21 @@ void threadB(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
        }
 }
 
+void threadC(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
+{
+       int32_t *bin = queue->write_prepare();
+       store_32(bin, 1);
+       queue->write_publish();
+
+       while (bin = queue->read_fetch()) {
+               printf("Read: %d\n", load_32(bin));
+               queue->read_consume();
+       }
+}
+
 #define MAXREADERS 3
 #define MAXWRITERS 3
+#define MAXRDWR 3
 
 #ifdef CONFIG_MPMC_READERS
 #define DEFAULT_READERS (CONFIG_MPMC_READERS)
@@ -39,7 +52,13 @@ void threadB(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
 #define DEFAULT_WRITERS 2
 #endif
 
-int readers = DEFAULT_READERS, writers = DEFAULT_WRITERS;
+#ifdef CONFIG_MPMC_RDWR
+#define DEFAULT_RDWR (CONFIG_MPMC_RDWR)
+#else
+#define DEFAULT_RDWR 0
+#endif
+
+int readers = DEFAULT_READERS, writers = DEFAULT_WRITERS, rdwr = DEFAULT_RDWR;
 
 void print_usage()
 {
@@ -84,7 +103,7 @@ void process_params(int argc, char **argv)
 int user_main(int argc, char **argv)
 {
        struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> queue;
-       thrd_t A[MAXWRITERS], B[MAXREADERS];
+       thrd_t A[MAXWRITERS], B[MAXREADERS], C[MAXRDWR];
 
        /* Note: optarg() / optind is broken in model-checker - workaround is
         * to just copy&paste this test a few times */
@@ -105,10 +124,15 @@ int user_main(int argc, char **argv)
        for (int i = 0; i < readers; i++)
                thrd_create(&B[i], (thrd_start_t)&threadB, &queue);
 
+       for (int i = 0; i < rdwr; i++)
+               thrd_create(&C[i], (thrd_start_t)&threadC, &queue);
+
        for (int i = 0; i < writers; i++)
                thrd_join(A[i]);
        for (int i = 0; i < readers; i++)
                thrd_join(B[i]);
+       for (int i = 0; i < rdwr; i++)
+               thrd_join(C[i]);
 
        printf("Threads complete\n");
 
index dc2b5618771774238c1c16f97efa87262da182a4..918415fa99278e0a8cc3d47622f84de00749445c 100644 (file)
@@ -38,6 +38,8 @@ public:
 
                        if ( m_rdwr.compare_exchange_weak(rdwr,rdwr+(1<<16),mo_acq_rel) )
                                break;
+                       else
+                               thrd_yield();
                }
 
                // (*1)
@@ -69,6 +71,8 @@ public:
 
                        if ( m_rdwr.compare_exchange_weak(rdwr,(rd<<16) | ((wr+1)&0xFFFF),mo_acq_rel) )
                                break;
+                       else
+                               thrd_yield();
                }
 
                // (*1)