From 0d3d0d7d866909e132d4982d9a84f91e2ac81842 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 24 Jun 2019 14:54:17 -0600 Subject: [PATCH] thread: add notes on the behavior of futures --- racket/src/thread/README.txt | 37 ++++++++++++++++++++++++++++++++++++ racket/src/thread/future.rkt | 3 +++ 2 files changed, 40 insertions(+) diff --git a/racket/src/thread/README.txt b/racket/src/thread/README.txt index 7d3c793e51..b648f5a8eb 100644 --- a/racket/src/thread/README.txt +++ b/racket/src/thread/README.txt @@ -6,3 +6,40 @@ Core engine support must be provided by a more primitive layer. The more primitive layer must also provide `break-enabled-key` and special handling for looking up a mark with that key so that an egine-specific default thread cell is produced. + +Futures +------- + +The implementation of futures here has different behavior than in the +original Racket implementation: + + - Many more primitive operations are "safe" in the sense of allowing + a future to keep running in parallel. For example, operations on + mutable `eq?` and `eqv?` hash tables are safe, as are `equal?` and + `equal-hash-code`. + + Any attempt to enter atomic mode at the level of Racket threads (as + implemented in this layer) is treated as unsafe and will block the + future. For example, attempting to use a port will invariably go + into atomic mode, so port operations are still "unsafe". Any + attempt to use a semaphore or channel will also involve atomic + mode, so those are unsafe in the sense of blocking a fututre. + + Attempting to use any operation that depends on the current + continuation or the current thread will also block, as it must. + However, a continuation-sensitive operation can succeed if it is + delimited by a prompt that is shallower in the continuation than + the future's start; that's an improvement over the original Racket + implementation. + + - A blocked future becomes permanently ineligible for running in + parallel. That is, if a future hits an unsafe operation, the future + won't switch to the main thread just long enough to perform the + operation and then switch back to parallel mode. + + To put is another way, there are no operations that trigger a 'sync + logging output instead of a 'block output. That's main because so + many more operations are safe. A second reason is that the futures + implementation has a finer-grained view of a computation so that it + doesn't see operations like `fprintf`; it sees only `start-atomic` + as an unsafe step inside `fprintf`. diff --git a/racket/src/thread/future.rkt b/racket/src/thread/future.rkt index 227db9c4e9..24fbb315ea 100644 --- a/racket/src/thread/future.rkt +++ b/racket/src/thread/future.rkt @@ -18,6 +18,9 @@ "future-lock.rkt" "future-logging.rkt") +;; See "README.txt" for some general information about this +;; implementation of futures. + (provide init-future-place! futures-enabled? future