return type == ATOMIC_WRITE || type == ATOMIC_RMW || type == ATOMIC_INIT;
}
+bool ModelAction::could_be_write() const
+{
+ return is_write() || is_rmwr();
+}
+
bool ModelAction::is_rmwr() const
{
return type == ATOMIC_RMWR;
// Explore interleavings of seqcst writes to guarantee total order
// of seq_cst operations that don't commute
- if ((is_write() || act->is_write()) && is_seqcst() && act->is_seqcst())
+ if ((could_be_write() || act->could_be_write()) && is_seqcst() && act->is_seqcst())
return true;
// Explore synchronizing read/write pairs
- if (is_read() && is_acquire() && act->is_write() && act->is_release())
+ if (is_read() && is_acquire() && act->could_be_write() && act->is_release())
return true;
// Otherwise handle by reads_from relation
bool is_failed_trylock() const;
bool is_read() const;
bool is_write() const;
+ bool could_be_write() const;
bool is_rmwr() const;
bool is_rmwc() const;
bool is_rmw() const;
params->maxfuturedelay = 100;
params->fairwindow = 0;
params->enabledcount = 1;
+ params->bound = 0;
}
static void print_usage(struct model_params *params) {
" enabled sufficiently many times should receive\n"
" priority for execution. Default: %d\n"
"-e Enabled count. Default: %d\n"
+"-b Upper length bound. Default: %d\n"
"-- Program arguments follow.\n\n",
-params->maxreads, params->maxfuturedelay, params->fairwindow, params->enabledcount);
+params->maxreads, params->maxfuturedelay, params->fairwindow, params->enabledcount, params->bound);
exit(EXIT_SUCCESS);
}
static void parse_options(struct model_params *params, int *argc, char ***argv) {
- const char *shortopts = "hm:s:f:e:";
+ const char *shortopts = "hm:s:f:e:b:";
int opt;
bool error = false;
while (!error && (opt = getopt(*argc, *argv, shortopts)) != -1) {
case 'e':
params->enabledcount = atoi(optarg);
break;
+ case 'b':
+ params->bound = atoi(optarg);
+ break;
case 'm':
params->maxreads = atoi(optarg);
break;
DEBUG("Number of acquires waiting on pending release sequences: %zu\n",
pending_rel_seqs->size());
- if (isfinalfeasible() || DBG_ENABLED())
+
+ if (isfinalfeasible() || (params.bound != 0 && priv->used_sequence_numbers > params.bound ) || DBG_ENABLED() )
print_summary();
if ((diverge = get_next_backtrack()) == NULL)
curr->print();
}
- if (curr->get_sleep_flag()) {
+ if (curr->get_sleep_flag() && ! curr->is_seqcst()) {
if (sleep_can_read_from(curr, act))
curr->get_node()->add_read_from(act);
} else
if (!isfeasible())
return false;
+ if (params.bound != 0) {
+ if (priv->used_sequence_numbers > params.bound) {
+ return false;
+ }
+ }
+
DEBUG("(%d, %d)\n", curr ? id_to_int(curr->get_id()) : -1,
next ? id_to_int(next->get_id()) : -1);
int maxfuturedelay;
unsigned int fairwindow;
unsigned int enabledcount;
+ unsigned int bound;
};
struct PendingFutureValue {