Merge remote-tracking branch 'private/master'
[cdsspec-compiler.git] / main.cc
1 /** @file main.cc
2  *  @brief Entry point for the model checker.
3  */
4
5 #include <unistd.h>
6 #include <getopt.h>
7
8 #include "common.h"
9 #include "output.h"
10
11 #include "datarace.h"
12
13 /* global "model" object */
14 #include "model.h"
15 #include "params.h"
16 #include "snapshot-interface.h"
17 #include "scanalysis.h"
18
19 static void param_defaults(struct model_params *params)
20 {
21         params->maxreads = 0;
22         params->maxfuturedelay = 6;
23         params->fairwindow = 0;
24         params->yieldon = false;
25         params->yieldblock = false;
26         params->sc_trace_analysis = false;
27         params->enabledcount = 1;
28         params->bound = 0;
29         params->maxfuturevalues = 0;
30         params->expireslop = 4;
31         params->verbose = !!DBG_ENABLED();
32         params->uninitvalue = 0;
33 }
34
35 static void print_usage(const char *program_name, struct model_params *params)
36 {
37         /* Reset defaults before printing */
38         param_defaults(params);
39
40         model_print(
41 "Copyright (c) 2013 Regents of the University of California. All rights reserved.\n"
42 "Distributed under the GPLv2\n"
43 "Written by Brian Norris and Brian Demsky\n"
44 "\n"
45 "Usage: %s [MODEL-CHECKER OPTIONS] -- [PROGRAM ARGS]\n"
46 "\n"
47 "MODLE-CHECKER OPTIONS can be any of the model-checker options listed below. Arguments\n"
48 "provided after the `--' (the PROGRAM ARGS) are passed to the user program.\n"
49 "\n"
50 "Model-checker options:\n"
51 "-h, --help                  Display this help message and exit\n"
52 "-m, --liveness=NUM          Maximum times a thread can read from the same write\n"
53 "                              while other writes exist.\n"
54 "                              Default: %d\n"
55 "-M, --maxfv=NUM             Maximum number of future values that can be sent to\n"
56 "                              the same read.\n"
57 "                              Default: %d\n"
58 "-s, --maxfvdelay=NUM        Maximum actions that the model checker will wait for\n"
59 "                              a write from the future past the expected number\n"
60 "                              of actions.\n"
61 "                              Default: %d\n"
62 "-S, --fvslop=NUM            Future value expiration sloppiness.\n"
63 "                              Default: %u\n"
64 "-y, --yield                 Enable CHESS-like yield-based fairness support.\n"
65 "                              Default: %s\n"
66 "-Y, --yieldblock            Prohibit an execution from running a yield.\n"
67 "                              Default: %s\n"
68 "-f, --fairness=WINDOW       Specify a fairness window in which actions that are\n"
69 "                              enabled sufficiently many times should receive\n"
70 "                              priority for execution (not recommended).\n"
71 "                              Default: %d\n"
72 "-e, --enabled=COUNT         Enabled count.\n"
73 "                              Default: %d\n"
74 "-b, --bound=MAX             Upper length bound.\n"
75 "                              Default: %d\n"
76 "-v, --verbose               Print verbose execution information.\n"
77 "-u, --uninitialized=VALUE   Return VALUE any load which may read from an\n"
78 "                              uninitialized atomic.\n"
79 "                              Default: %u\n"
80 "-c, --analysis              Use SC Trace Analysis.\n"
81 " --                         Program arguments follow.\n\n",
82                 program_name,
83                 params->maxreads,
84                 params->maxfuturevalues,
85                 params->maxfuturedelay,
86                 params->expireslop,
87                 params->yieldon ? "enabled" : "disabled",
88                 params->yieldblock ? "enabled" : "disabled",
89                 params->fairwindow,
90                 params->enabledcount,
91                 params->bound,
92                 params->uninitvalue);
93         exit(EXIT_SUCCESS);
94 }
95
96 static void parse_options(struct model_params *params, int argc, char **argv)
97 {
98         const char *shortopts = "hyYcm:M:s:S:f:e:b:u:v::";
99         const struct option longopts[] = {
100                 {"help", no_argument, NULL, 'h'},
101                 {"liveness", required_argument, NULL, 'm'},
102                 {"maxfv", required_argument, NULL, 'M'},
103                 {"maxfvdelay", required_argument, NULL, 's'},
104                 {"fvslop", required_argument, NULL, 'S'},
105                 {"fairness", required_argument, NULL, 'f'},
106                 {"yield", no_argument, NULL, 'y'},
107                 {"yieldblock", no_argument, NULL, 'Y'},
108                 {"enabled", required_argument, NULL, 'e'},
109                 {"bound", required_argument, NULL, 'b'},
110                 {"verbose", optional_argument, NULL, 'v'},
111                 {"uninitialized", optional_argument, NULL, 'u'},
112                 {"analysis", optional_argument, NULL, 'c'},
113                 {0, 0, 0, 0} /* Terminator */
114         };
115         int opt, longindex;
116         bool error = false;
117         while (!error && (opt = getopt_long(argc, argv, shortopts, longopts, &longindex)) != -1) {
118                 switch (opt) {
119                 case 'h':
120                         print_usage(argv[0], params);
121                         break;
122                 case 's':
123                         params->maxfuturedelay = atoi(optarg);
124                         break;
125                 case 'S':
126                         params->expireslop = atoi(optarg);
127                         break;
128                 case 'f':
129                         params->fairwindow = atoi(optarg);
130                         break;
131                 case 'e':
132                         params->enabledcount = atoi(optarg);
133                         break;
134                 case 'b':
135                         params->bound = atoi(optarg);
136                         break;
137                 case 'm':
138                         params->maxreads = atoi(optarg);
139                         break;
140                 case 'M':
141                         params->maxfuturevalues = atoi(optarg);
142                         break;
143                 case 'v':
144                         params->verbose = optarg ? atoi(optarg) : 1;
145                         break;
146                 case 'u':
147                         params->uninitvalue = atoi(optarg);
148                         break;
149                 case 'c':
150                         params->sc_trace_analysis = true;
151                         break;
152                 case 'y':
153                         params->yieldon = true;
154                         break;
155                 case 'Y':
156                         params->yieldblock = true;
157                         break;
158                 default: /* '?' */
159                         error = true;
160                         break;
161                 }
162         }
163
164         /* Pass remaining arguments to user program */
165         params->argc = argc - (optind - 1);
166         params->argv = argv + (optind - 1);
167
168         /* Reset program name */
169         params->argv[0] = argv[0];
170
171         /* Reset (global) optind for potential use by user program */
172         optind = 1;
173
174         if (error)
175                 print_usage(argv[0], params);
176 }
177
178 int main_argc;
179 char **main_argv;
180
181 static void install_trace_analyses(const ModelExecution *execution)
182 {
183         if (model->params.sc_trace_analysis)
184                 model->add_trace_analysis(new SCAnalysis(execution));
185 }
186
187 /** The model_main function contains the main model checking loop. */
188 static void model_main()
189 {
190         struct model_params params;
191
192         param_defaults(&params);
193
194         parse_options(&params, main_argc, main_argv);
195
196         //Initialize race detector
197         initRaceDetector();
198
199         snapshot_stack_init();
200
201         model = new ModelChecker(params);
202         install_trace_analyses(model->get_execution());
203
204         snapshot_record(0);
205         model->run();
206         delete model;
207
208         DEBUG("Exiting\n");
209 }
210
211 /**
212  * Main function.  Just initializes snapshotting library and the
213  * snapshotting library calls the model_main function.
214  */
215 int main(int argc, char **argv)
216 {
217         main_argc = argc;
218         main_argv = argv;
219
220         /* Configure output redirection for the model-checker */
221         redirect_output();
222
223         /* Let's jump in quickly and start running stuff */
224         snapshot_system_init(10000, 1024, 1024, 4000, &model_main);
225 }