Brian Norris [Fri, 7 Dec 2012 06:53:07 +0000 (22:53 -0800)]
model/action: bugfix - UNINIT actions do not have a Node
Fix the one place where ModelChecker looks for a Node in an UNINIT
action.
This also adds an ASSERT() within ModelAction to prevent calling
get_node() on an UNINIT action. It is technically OK to call get_node()
in this case, but most callers don't check for NULL, so it's better to
just catch the ASSERT() for this unwanted special case.
Brian Norris [Fri, 7 Dec 2012 06:45:23 +0000 (22:45 -0800)]
model: remove old "uninitialized" bug check
The previously-existing bug check is not fully correct and has been
replaced with explicit UNINIT actions that, when read from, trigger a
bug assertion.
Brian Norris [Fri, 7 Dec 2012 06:42:10 +0000 (22:42 -0800)]
model: generate UNINIT actions as new atomic operations form
The first time an atomic variable is accessed, we need to add an
appropriate UNINIT action to the ModelChecker data structures. We assign
these ModelActions to the special model-checker thread (Thread 0). Note
that these actions will *not* appear in the NodeStack and will not be
explored in check_current_action, etc.
Brian Norris [Fri, 7 Dec 2012 06:40:05 +0000 (22:40 -0800)]
action: move ModelAction::get_node to action.cc
This function needs to expand a bit, so move it to the implementation
file.
Brian Norris [Fri, 7 Dec 2012 06:03:53 +0000 (22:03 -0800)]
model: add helper for allocating new UNINIT actions
These UNINIT actions will be special; they won't enter the NodeStack,
and so they need to be snapshot-allocated. That way, they will roll-back
with the execution, instead of requiring manual deletion.
Brian Norris [Fri, 7 Dec 2012 05:50:33 +0000 (21:50 -0800)]
mymemory: add placement new
I will need to use the placement new operator, if I want to allocate an
object with an allocator other than the one I established (SNAPSHOTALLOC
vs. MODELALLOC).
Brian Norris [Fri, 7 Dec 2012 06:02:03 +0000 (22:02 -0800)]
model: clear a ModelAction's reads-from properly
Brian Norris [Fri, 7 Dec 2012 05:12:29 +0000 (21:12 -0800)]
action: add ATOMIC_UNINIT type
Adding a new type of "uninitialized atomic" action, to serve as a store
which, if any load is able to "see" this store, constitutes an
uninitialized load - a bug in the user program. It has to act like a
store operation, but it triggers a bug (ModelChecker::assert_bug) if any
load tries to read from it.
Brian Norris [Thu, 6 Dec 2012 22:10:28 +0000 (14:10 -0800)]
Makefile: build dependencies in .*.o.d files
My previous attempts at fixing dependency generation actually cause
full recompilation every time a file is changed. Apparently, it'll work
best if each target object has its own dependency file. i.e., target
'model.o' has a corresponding '.model.o.d' which holds its dependency
information.
Brian Norris [Thu, 6 Dec 2012 22:19:45 +0000 (14:19 -0800)]
Makefile: rename variable to be more clear
Brian Norris [Thu, 6 Dec 2012 23:30:44 +0000 (15:30 -0800)]
model: refactoring + spacing
Brian Norris [Thu, 6 Dec 2012 23:30:24 +0000 (15:30 -0800)]
schedule: add is_sleep_set(thread)
Brian Norris [Thu, 6 Dec 2012 23:29:26 +0000 (15:29 -0800)]
schedule: add const
Brian Norris [Thu, 6 Dec 2012 23:26:30 +0000 (15:26 -0800)]
threads: add const
Brian Norris [Thu, 6 Dec 2012 20:13:25 +0000 (12:13 -0800)]
notes: fence: replace variables to match 29.8
I had some remaining edits to do for my notes 29.8, to match back with
the specification's variables (X, Y, A, B).
Brian Norris [Thu, 6 Dec 2012 19:51:15 +0000 (11:51 -0800)]
notes: fence: rename variables to match spec better
Originally, I purposely renamed these since I needed to introduce more
variables than were in the spec. But it turns out I can make this match
the spec pretty well.
Now: A, B, X, and Y fulfill the same roles as in the original C++
specification statements. I only introduce my new variable as W, when
needed. This also makes sense because W is a Write.
Also, I delete an extraneous paragraph that duplicated a piece of the
spec.
Brian Norris [Thu, 6 Dec 2012 00:41:17 +0000 (16:41 -0800)]
notes: fence: add release/acquire fence notes
I remove the copied-and-pasted algorithm pseudocode, since I didn't feel
like it was necessary to tweak the pseudocode to include fences. I might
change my mind later.
Brian Norris [Wed, 5 Dec 2012 23:35:02 +0000 (15:35 -0800)]
notes: fence: more updates
Brian Norris [Wed, 5 Dec 2012 23:29:32 +0000 (15:29 -0800)]
doc: notes: fence: update fence notes
The backtracking and seq-cst/MO constraints are complete, but the
release/acquire, etc.
Brian Norris [Wed, 5 Dec 2012 20:20:31 +0000 (12:20 -0800)]
model: stop thread-trace search once edge is added
Once an edge has been added from 'act' to the current thread (or the
'rf' thread), we don't need to continue to search for more edges.
Brian Norris [Wed, 5 Dec 2012 02:23:52 +0000 (18:23 -0800)]
doc: notes: add fences note
This note is incomplete.
Brian Norris [Wed, 5 Dec 2012 00:40:32 +0000 (16:40 -0800)]
model: fix bugs in fence-acquire synchronization
(1) In the fence-acquire search, we can't stop searching for prior loads
when we reach the current action; we must continue to search until
we find a *different* fence-acquire (or the beginning of the thread)
(2) The load action does not synchronize in fence-acquire
synchronization: the fence should synchronize. This was just a typo
(act vs. curr).
Brian Norris [Wed, 5 Dec 2012 00:04:40 +0000 (16:04 -0800)]
impatomic: move atomic_{thread,signal}_fence() to namespace std
Brian Norris [Tue, 4 Dec 2012 23:36:40 +0000 (15:36 -0800)]
run.sh: print the command that runs
This will help understanding typos, script bugs, etc.
Brian Norris [Tue, 4 Dec 2012 02:30:18 +0000 (18:30 -0800)]
model: add process_fence()
process_fence() will only handle fence-acquire. Fence-relaxed is a
no-op; fence-release is only logged for later use; and fence-seq-cst
takes release/acquire semantics, plus some mo-graph rules which apply to
reads/reads (see {r,w}_modification_order).
Brian Norris [Tue, 4 Dec 2012 23:14:29 +0000 (15:14 -0800)]
model: distinguish between 'read' and 'acquire' in release sequences
When using fences, we may have a fence-acquire preceded by a non-acquire
load, where the load takes part in a "hypothetical release sequence" (as
named by Mathematizing C++). So, I add a parameter to
get_release_seq_heads() and to struct release_seq so that we record the
'acquire' operation separately from the 'read'.
For our traditional release sequences, 'acquire' and 'read' will be the
same ModelAction. But fence-acquire support will utilize distinct
actions.
Brian Norris [Tue, 4 Dec 2012 22:08:13 +0000 (14:08 -0800)]
model: add read-acquire/fence-release support
C++ Section 29.8, statement 3: gives conditions under which a
read-acquire and fence-release might synchronize. It's easy enough to
integrate into our existing release sequence code.
Brian Norris [Tue, 4 Dec 2012 02:29:42 +0000 (18:29 -0800)]
action: add is_thread_start()
Brian Norris [Tue, 4 Dec 2012 02:23:22 +0000 (18:23 -0800)]
model: privatize a few interfaces
These functions were only public for ModelAction::read_from, which has
now been internalized into ModelChecker.
Brian Norris [Tue, 4 Dec 2012 02:14:55 +0000 (18:14 -0800)]
model/action: move complicated read_from logic into model.cc
The release sequence wrapper logic will only get more complicated, so
rather than spreading across two files and exporting more interfaces,
just integrate into ModelChecker.
Brian Norris [Tue, 4 Dec 2012 00:51:43 +0000 (16:51 -0800)]
model: record last fence-release from each thread
Brian Norris [Tue, 4 Dec 2012 00:43:19 +0000 (16:43 -0800)]
action: record last fence release from the current thread
Brian Norris [Tue, 4 Dec 2012 00:58:58 +0000 (16:58 -0800)]
model: remove extraneous copy-and-paste
Brian Norris [Tue, 4 Dec 2012 00:17:08 +0000 (16:17 -0800)]
model: add seq-cst fence rules
Add mo_graph constraints, from statements 4-6 in C++ Section 29.3. There
are probably more constraints we can choose for building may-read-from /
future values.
Brian Norris [Tue, 4 Dec 2012 00:00:33 +0000 (16:00 -0800)]
action/model: backtrack for seq-cst and release/acquire fences
Extends backtracking support to explore all interleavings of conflicting
seq-cst fences and potentially-synchronizing write/read/fence pairs.
Brian Norris [Mon, 3 Dec 2012 21:27:58 +0000 (13:27 -0800)]
action: allow fence ModelActions to have location == NULL
Brian Norris [Mon, 3 Dec 2012 21:05:55 +0000 (13:05 -0800)]
model: refactor build_reads_from_past
Just rearrange the logic a little, to prepare for some other additions.
Brian Norris [Sat, 1 Dec 2012 02:46:28 +0000 (18:46 -0800)]
model: add get_last_seq_cst_fence
Brian Norris [Mon, 3 Dec 2012 19:36:50 +0000 (11:36 -0800)]
model: rename last_seq_cst -> last_sc_write
Brian Norris [Sat, 1 Dec 2012 01:54:58 +0000 (17:54 -0800)]
model: rename get_last_seq_cst -> get_last_seq_cst_write
Brian Norris [Fri, 30 Nov 2012 23:05:44 +0000 (15:05 -0800)]
impatomic: add atomic_{thread,signal}_fence() definitions
The impatomic.h header is outdated. Additional information from the ISO
papers N2633, N2731, and N2752 have limited the "fence()" support to
just these two functions.
Brian Norris [Fri, 30 Nov 2012 22:57:39 +0000 (14:57 -0800)]
impatomic: remove fence member functions
Recent C/C++ drafts do not include fence() as a member function for any
object. All fences apply globally (not to any particular object).
[ These changes came in the ISO papers N2633, N2731, N2752 ]
So, I discard any reference to a fence that is associated with an object
(i.e., as a member of an object or with an object parameter).
I will implement a replacement shortly, which just uses the
_ATOMIC_FENCE_(order) macro.
Brian Norris [Wed, 21 Nov 2012 02:27:20 +0000 (18:27 -0800)]
Makefile: fix dependency generation
- Don't regenerate make.deps for 'make clean' target
- Place the dependency on make.deps at the correct level; all "%.o"
generations depend on it, not the top-level 'all' target
Brian Norris [Tue, 20 Nov 2012 04:53:46 +0000 (20:53 -0800)]
model: remove <list> include
Brian Norris [Tue, 20 Nov 2012 04:51:04 +0000 (20:51 -0800)]
model: add const
Brian Norris [Tue, 20 Nov 2012 04:40:30 +0000 (20:40 -0800)]
schedule: rename get_enabled() -> get_enabled_array()
This function actually returns the array, not a single "enabled" status.
(There's a separate get_enabled() method for getting a single status.)
Brian Norris [Tue, 20 Nov 2012 04:33:53 +0000 (20:33 -0800)]
model: rename isfinalfeasible -> is_feasible_prefix_ignore_relseq
This more accurately reflects its use case and the fact that it is a
slightly-weaker version of isfeasibleprefix(). Also, I integrate it into
isfeasibleprefix(), to avoid re-writing the same conditions.
Brian Norris [Tue, 20 Nov 2012 04:29:34 +0000 (20:29 -0800)]
model: replace isfinalfeasible() with stronger check
The stronger isfeasibleprefix() check is not strictly necessary in these
cases, since we can ensure that promises are resolved before executing
these, but it make sense to have a well-defined "strength" to these
feasibility properties, then use the strongest strength that is useful.
Brian Norris [Tue, 20 Nov 2012 04:17:23 +0000 (20:17 -0800)]
model: privatize, move isfinalfeasible()
This function should go with all the other "feasible" functions.
Brian Norris [Tue, 20 Nov 2012 04:11:21 +0000 (20:11 -0800)]
model: rename some 'isfeasible...' functions to 'is_infeasible...'
These functions can be more accurately described as checking
*infeasibility*, not necessarily feasibility. This helps clarify their
purpose, at least for my understanding.
Brian Norris [Tue, 20 Nov 2012 04:03:35 +0000 (20:03 -0800)]
model: privatize some functions
Just kill finish_execution() while we're at it.
Brian Norris [Tue, 20 Nov 2012 03:47:11 +0000 (19:47 -0800)]
main: remove #include's
Brian Norris [Tue, 20 Nov 2012 03:40:12 +0000 (19:40 -0800)]
main: remove "pass-by-reference" editing in parse_options()
parse_options() can simply pass the argc/argv variables through the
model_checker_params struct now.
Also, document a few things.
Brian Norris [Tue, 20 Nov 2012 03:33:32 +0000 (19:33 -0800)]
threads: remove todo (long overdue)
Brian Norris [Tue, 20 Nov 2012 03:32:22 +0000 (19:32 -0800)]
main/model: move full user-program execution to ModelChecker::run
We don't really need the top-level ModelChecker execution loop to be in
main.cc; it should be exposed simply as a run() method.
Brian Norris [Tue, 20 Nov 2012 03:30:41 +0000 (19:30 -0800)]
model/main: add argc/argv parameter
ModelChecker will take care of launching the user program soon.
Brian Norris [Tue, 20 Nov 2012 03:15:47 +0000 (19:15 -0800)]
model: move flags to private 'model_snapshot_members'
Brian Norris [Tue, 20 Nov 2012 03:04:33 +0000 (19:04 -0800)]
model: add model_snapshot_members constructor/destructor
Brian Norris [Tue, 20 Nov 2012 02:40:50 +0000 (18:40 -0800)]
model: privatize set_assert()
Brian Norris [Tue, 20 Nov 2012 00:39:36 +0000 (16:39 -0800)]
run.sh: rewrite script to handle options more gracefully
Now you can do:
./run.sh [OPTIONS]
without having to specify a particular program (defaults to
./test/userprog.o).
Brian Norris [Tue, 20 Nov 2012 00:37:26 +0000 (16:37 -0800)]
output: don't redirect any output for DEBUG builds
Brian Norris [Mon, 19 Nov 2012 23:51:02 +0000 (15:51 -0800)]
README: add verbose (-v) argument
Brian Norris [Mon, 19 Nov 2012 21:10:07 +0000 (13:10 -0800)]
model: optimize get_last_conflict() search
Relaxed operations should never require backtracking, so don't even
bother with searching the list in such cases. I ran some simple
benchmarking tests with linuxrwlocks (timing results below). Also, perf
shows a significant decrease in % time spent in
ModelAction::could_synchronize_with.
------------
Before:
------------
$ time ./run.sh test/linuxrwlocks.o -f 10 -m 10
Number of complete, bug-free executions: 7110
Number of redundant executions: 29
Number of buggy executions: 0
Number of infeasible executions: 43578
Total executions: 50717
Total nodes created: 63463
real 0m7.274s
user 0m6.596s
sys 0m0.652s
2.10% linuxrwlocks.o libmodel.so [.] ModelAction::could_synchronize_with(ModelAction const*) const
------------
After:
------------
$ time ./run.sh test/linuxrwlocks.o -f 10 -m 10
Number of complete, bug-free executions: 7110
Number of redundant executions: 29
Number of buggy executions: 0
Number of infeasible executions: 43578
Total executions: 50717
Total nodes created: 63463
real 0m6.690s
user 0m6.000s
sys 0m0.664s
0.73% linuxrwlocks.o libmodel.so [.] ModelAction::could_synchronize_with(ModelAction const*) const
Brian Norris [Mon, 19 Nov 2012 21:09:29 +0000 (13:09 -0800)]
action: add is_relaxed() function
Brian Norris [Sat, 17 Nov 2012 08:11:27 +0000 (00:11 -0800)]
common: update comment
Brian Norris [Sat, 17 Nov 2012 08:01:18 +0000 (00:01 -0800)]
model: add "# redundant" stat
Brian Norris [Sat, 17 Nov 2012 07:55:12 +0000 (23:55 -0800)]
model: refactor end-of-execution output
Brian Norris [Sat, 17 Nov 2012 07:51:59 +0000 (23:51 -0800)]
model: print_summary() should be const
Brian Norris [Sat, 17 Nov 2012 04:23:15 +0000 (20:23 -0800)]
model/main: disable most printing by default, add verbosity
Adds a '-v' parameter for printing verbose info on a non-DEBUG build.
This effectively creates 3 classes of runs:
- Default build, no -v: only prints info when discovering a buggy
execution
- Default build, -v: prints more verbose information, on all feasible
executions (buggy or non-buggy)
- Debug build: Built with 'make debug'. Most verbose; prints everything
for every execution, including infeasible executions. Also prints
DEBUG() prints (as usual).
Brian Norris [Sat, 17 Nov 2012 04:07:57 +0000 (20:07 -0800)]
output redirection
Brian Norris [Sat, 17 Nov 2012 01:45:23 +0000 (17:45 -0800)]
model: print execution # with trace
Since stats won't be printed regularly, we still want a measure of
"how many executions have run" when we print a summary trace.
Brian Norris [Sat, 17 Nov 2012 01:44:50 +0000 (17:44 -0800)]
print stats only at end of execution
Brian Norris [Fri, 16 Nov 2012 23:23:40 +0000 (15:23 -0800)]
printf -> model_print
As we move toward redirecting program output, we will need a special
printf function for model-checking prints. Just define a simple
model_print() for now.
Brian Norris [Fri, 16 Nov 2012 23:05:51 +0000 (15:05 -0800)]
model: correct plural ("bug" or "bugs")
Brian Norris [Fri, 16 Nov 2012 22:58:32 +0000 (14:58 -0800)]
model: rework assert_bug() and assert_user_bug() interfaces
We don't need assert_bug_immediate(), and we don't need some of the
optional parameters in assert_bug(). Just simplify down to two
interfaces:
assert_bug()
assert_user_bug()
The former is useful for all bugs triggered from model-checker threads,
and the latter is useful from a user-thread context, so that you can
immediately switch to the model-checking context and exit the program -
but *only if* the trace is currently-feasible.
Brian Norris [Fri, 16 Nov 2012 22:44:32 +0000 (14:44 -0800)]
dataraces: don't print an uninformative "Data race" bug msg
Now that checkDataRaces() handles all bug reporting and assertions on
its own, we don't need an additional bug report message printed by the
caller. In some cases, this means the caller doesn't have any action to
take. In one case (a race immediately-realized from a user thread), we
still need to "bail out" to the model-checker.
Brian Norris [Fri, 16 Nov 2012 22:38:26 +0000 (14:38 -0800)]
datarace: redirect "Data race @ ..." messages to model-checker bug list
Data race information was previously printed in multiple ways: through
the datarace.cc printRace() method and through the model-checker
assert_bug() method. Start unifying that.
Other notes:
- Data race objects probably should be freed (even though they are
snapshotted). I fix this.
- Races could be printed more than once previously, since the
unrealizedraces vector was never cleared of realized races. Now, we
clear this vector every time we process it (in a feasible execution),
either stashing a bug message or dropping the race entirely.
Brian Norris [Fri, 16 Nov 2012 21:59:03 +0000 (13:59 -0800)]
datarace: change "Datarace" to "Data race"
Brian Norris [Fri, 16 Nov 2012 20:02:10 +0000 (12:02 -0800)]
model: restructure statistics records
Brian Norris [Fri, 16 Nov 2012 02:01:31 +0000 (18:01 -0800)]
model: annotate SNAPSHOT for bug_message
Since we use operator new with bug_message, it needs to be marked
SNAPSHOTALLOC.
Brian Norris [Fri, 16 Nov 2012 01:51:43 +0000 (17:51 -0800)]
model: temporary fix for uninitialized loads
This patch does two things:
(1) Convert 'set_assert()' to 'assert_bug()' to provide:
- More unified bug printing
- Only printing the bug for a feasible prefix
(2) Avoids the work_queue loop if a bug was asserted
Part (1) mostly provides some cosmetic fixes.
Part (2) prevents an ASSERT() from being thrown in future values, since
we don't abort the trace early enough when there's nothing to read from.
This all needs better treatment of uninitialized loads, as there are
some loose ends.
Brian Norris [Thu, 15 Nov 2012 21:50:40 +0000 (13:50 -0800)]
assert bugs through common interface
- User-provied assertions (MODEL_ASSERT())
- Data races
- Deadlocks
- Unlock before lock
Notably, I have not yet converted the "uninitialized load" bug, because
it actually isn't correct yet. It needs to handle future values and lazy
synchronization better.
Brian Norris [Thu, 15 Nov 2012 21:33:13 +0000 (13:33 -0800)]
model: print bug reports at end of each execution
This ensures:
- that bug reports are printed only at the end of feasible executions
- that execution summaries are printed only for complete (or halted and
buggy) executions that are feasible
- that all bug reports will have the same formatting (at least, ones
that use the 'assert_bug()' function)
Note that deadlocks are the only bugs reported this way right now. I'll
fix that up soon.
Brian Norris [Thu, 15 Nov 2012 21:25:35 +0000 (13:25 -0800)]
model: add bug reporting framework
This will help clean up bug reporting so that bugs are only printed for
complete, valid executions.
Brian Norris [Thu, 15 Nov 2012 21:29:44 +0000 (13:29 -0800)]
model: remove unnecessary DEBUG()
Brian Norris [Thu, 15 Nov 2012 20:43:23 +0000 (12:43 -0800)]
model: use snapshot_calloc()
Also, might as well free priv on destruction.
Brian Norris [Thu, 15 Nov 2012 20:21:45 +0000 (12:21 -0800)]
model: add 'const'
Brian Norris [Thu, 15 Nov 2012 00:46:03 +0000 (16:46 -0800)]
model: routine to check if execution is complete
Not used yet.
Brian Demsky [Thu, 15 Nov 2012 07:29:52 +0000 (23:29 -0800)]
make compile on linux...needed string.h
Brian Demsky [Thu, 15 Nov 2012 07:27:30 +0000 (23:27 -0800)]
Merge branch 'master' of /home/git/model-checker
Brian Demsky [Thu, 15 Nov 2012 07:26:45 +0000 (23:26 -0800)]
optimize hashtable so we don't always build new ones for cyclegraph check
Brian Demsky [Thu, 15 Nov 2012 06:45:26 +0000 (22:45 -0800)]
remove hashtable functionality
Brian Demsky [Thu, 15 Nov 2012 06:44:33 +0000 (22:44 -0800)]
make hashtables only contain primitive types or pointers
Brian Demsky [Thu, 15 Nov 2012 04:55:23 +0000 (20:55 -0800)]
Merge branch 'master' of /home/git/model-checker
Brian Demsky [Thu, 15 Nov 2012 04:55:06 +0000 (20:55 -0800)]
avoid warning
Brian Demsky [Thu, 15 Nov 2012 02:15:04 +0000 (18:15 -0800)]
merge
Merge branch 'master' of ssh://demsky.eecs.uci.edu/home/git/model-checker
Conflicts:
config.h
model.cc
Brian Demsky [Thu, 15 Nov 2012 02:11:29 +0000 (18:11 -0800)]
optimization...don't calloc the datarace tables every single time...it is really expensive for rollback
Brian Norris [Thu, 15 Nov 2012 00:30:39 +0000 (16:30 -0800)]
model: remove useless special case
Why do we want to print races, etc., when exiting due to execution
length bound? If you want that, just enable debug prints.
Brian Norris [Wed, 14 Nov 2012 23:56:55 +0000 (15:56 -0800)]
model: don't export Scheduler
I removed any users of the get_scheduler() function.
Brian Norris [Wed, 14 Nov 2012 23:55:59 +0000 (15:55 -0800)]
model/promise: use ModelChecker is_enabled() interface
class Promise should not need to access Scheduler directly. Use the
ModelChecker interface.