Reintroduce invariant() as a wrapper around watch and export watch in __all__
Major bugfix: blank out new_watchers_to_run after our initial run. Failing to do so caused an infinite loop when running the version of examples/threadpool1.py that I'll be committing shortly.
Change ThreadPool to use stm.watch to handle spawning workers
Split timeouts out of retry into a separate function, elapsed.
Additional comments and documentation
Rewrite everything using retry(resume_*=...) to use elapsed() instead, and make elapsed consider None to be an infinite timeout (such that elapsed(None) always returns False)
Add an atexit handler to eventloop.py to wait until all events on the default event loop have been processed before shutting down
Note a deficiency of elapsed() (it doesn't cause a watcher using it to be automatically re-run in the future) and note that or_else reverts its functions when they throw exceptions
Add stm.utils.would_block, a function that returns True if the passed-in function would retry were it invoked right now
Notes on using elapsed() inside watchers
Implement _ThreadWaiter and switch retry-related things to use it. This has not yet been tested.

_PipeWaiter will come soon.
Add proper support for using elapsed() inside watchers.

One can now do things like schedule functions to execute in the future with:

@watch(lambda: elapsed(time=...))
def _(result):
    if result:
        ...

but note that using elapsed(seconds=...) inside of a watcher will result in weird behavior, so don't do it.
Only take elapsed(time=...) calls into account when re-running watches. This isn't exactly the most intuitive way of doing it, but it's the best I've come up with under the circumstances.
Write _PipeWaiter, an efficient alternative to _ThreadWaiter, and use it by default on Linux. I've done some tests on it and it appears to work flawlessly.
Make _PipeWaiter happy when resume_at is None
Set the threadpool example's thread pool to use 50 threads with 100 tasks, a combination that performs quite poorly at present due to contention among the threads. This will serve as a good benchmark to see if the performance improvements I'm about to make to the core have any (and enough) effect.
Add and enable machinery to restrict concurrent transaction attempts. This greatly improves performance under heavy contention.

Also introduce an environment variable, PYTHON_STM_STATS, which can be set to 1 to dump statistics when the program exits.
Make the threadpool example even more demanding
Notes on a performance problem with ThreadPool
Change TObject to wrap each of its underlying TDict's values in TVars; see notes/stm-threadpool.txt for the rationale behind doing this.