bench.sh: fixup Brian D.'s script change
[model-checker-benchmarks.git] / mpmc-queue / mpmc-queue.cc
1 #include <inttypes.h>
2 #include <threads.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6
7 #include <librace.h>
8
9 #include "mpmc-queue.h"
10
11 void threadA(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
12 {
13         int32_t *bin = queue->write_prepare();
14         store_32(bin, 1);
15         queue->write_publish();
16 }
17
18 void threadB(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
19 {
20         int32_t *bin;
21         while (bin = queue->read_fetch()) {
22                 printf("Read: %d\n", load_32(bin));
23                 queue->read_consume();
24         }
25 }
26
27 void threadC(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
28 {
29         int32_t *bin = queue->write_prepare();
30         store_32(bin, 1);
31         queue->write_publish();
32
33         while (bin = queue->read_fetch()) {
34                 printf("Read: %d\n", load_32(bin));
35                 queue->read_consume();
36         }
37 }
38
39 #define MAXREADERS 3
40 #define MAXWRITERS 3
41 #define MAXRDWR 3
42
43 #ifdef CONFIG_MPMC_READERS
44 #define DEFAULT_READERS (CONFIG_MPMC_READERS)
45 #else
46 #define DEFAULT_READERS 2
47 #endif
48
49 #ifdef CONFIG_MPMC_WRITERS
50 #define DEFAULT_WRITERS (CONFIG_MPMC_WRITERS)
51 #else
52 #define DEFAULT_WRITERS 2
53 #endif
54
55 #ifdef CONFIG_MPMC_RDWR
56 #define DEFAULT_RDWR (CONFIG_MPMC_RDWR)
57 #else
58 #define DEFAULT_RDWR 0
59 #endif
60
61 int readers = DEFAULT_READERS, writers = DEFAULT_WRITERS, rdwr = DEFAULT_RDWR;
62
63 void print_usage()
64 {
65         printf("Error: use the following options\n"
66                 " -r <num>              Choose number of reader threads\n"
67                 " -w <num>              Choose number of writer threads\n");
68         exit(EXIT_FAILURE);
69 }
70
71 void process_params(int argc, char **argv)
72 {
73         const char *shortopts = "hr:w:";
74         int opt;
75         bool error = false;
76
77         while (!error && (opt = getopt(argc, argv, shortopts)) != -1) {
78                 switch (opt) {
79                 case 'h':
80                         print_usage();
81                         break;
82                 case 'r':
83                         readers = atoi(optarg);
84                         break;
85                 case 'w':
86                         writers = atoi(optarg);
87                         break;
88                 default: /* '?' */
89                         error = true;
90                         break;
91                 }
92         }
93
94         if (writers < 1 || writers > MAXWRITERS)
95                 error = true;
96         if (readers < 1 || readers > MAXREADERS)
97                 error = true;
98
99         if (error)
100                 print_usage();
101 }
102
103 int user_main(int argc, char **argv)
104 {
105         struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> queue;
106         thrd_t A[MAXWRITERS], B[MAXREADERS], C[MAXRDWR];
107
108         /* Note: optarg() / optind is broken in model-checker - workaround is
109          * to just copy&paste this test a few times */
110         //process_params(argc, argv);
111         printf("%d reader(s), %d writer(s)\n", readers, writers);
112
113 #ifndef CONFIG_MPMC_NO_INITIAL_ELEMENT
114         printf("Adding initial element\n");
115         int32_t *bin = queue.write_prepare();
116         store_32(bin, 17);
117         queue.write_publish();
118 #endif
119
120         printf("Start threads\n");
121
122         for (int i = 0; i < writers; i++)
123                 thrd_create(&A[i], (thrd_start_t)&threadA, &queue);
124         for (int i = 0; i < readers; i++)
125                 thrd_create(&B[i], (thrd_start_t)&threadB, &queue);
126
127         for (int i = 0; i < rdwr; i++)
128                 thrd_create(&C[i], (thrd_start_t)&threadC, &queue);
129
130         for (int i = 0; i < writers; i++)
131                 thrd_join(A[i]);
132         for (int i = 0; i < readers; i++)
133                 thrd_join(B[i]);
134         for (int i = 0; i < rdwr; i++)
135                 thrd_join(C[i]);
136
137         printf("Threads complete\n");
138
139         return 0;
140 }