From: Matt Birkholz Date: Thu, 12 Mar 2015 21:28:24 +0000 (-0700) Subject: smp: README.txt corrections and wordsmithing. Squash into 9969ff0. X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=6d06952713364c5bd445a9ff5397b405c153d64f;p=mit-scheme.git smp: README.txt corrections and wordsmithing. Squash into 9969ff0. --- diff --git a/README.txt b/README.txt index 0777f49a8..42c122ecc 100644 --- a/README.txt +++ b/README.txt @@ -12,17 +12,17 @@ business. What could go wrong? :-} * Multiple Machines -The current implementation assumes multiple OS threads (pthreads) run -multiple Scheme machines in the same address space, accessing a shared -heap. Each machine has thread-local registers and gets sole use of -stack and heap segments in the shared address space UNTIL a garbage -collection is signaled. During GC, one processor becomes "the GC -processor". It interrupts the others, waits for them to stop in a "GC -wait" state, then performs the garbage collection, tracing each -processor's stack as well as the usual roots. It evacuates objects -from each processor's local heap segment to the shared to_space. When -complete, each processor's heap segment is empty and the pointers in -its stack all point to the new shared heap. +The current implementation assumes multiple OS threads (pthreads) each +run a Scheme machine and access a shared heap. Each machine has +thread-local registers and gets sole use of stack and heap segments in +the shared address space UNTIL a garbage collection is signaled. +During GC, one processor becomes "the GC processor". It interrupts +the others, waits for them to stop in a "GC wait" state, then performs +the garbage collection, tracing each processor's stack as well as the +usual roots. It evacuates objects from each processor's local heap +segment to the shared to_space. When complete, each processor's heap +segment is empty and the pointers in its stack all point to the new +shared heap. When not garbage collecting (or waiting for a GC to complete), or running, a processor is "idle" -- blocked waiting for an interrupt. @@ -35,18 +35,18 @@ and continues it until interrupted, or until the thread is no longer runnable (i.e. dead or blocked). The "I/O waiter" is the "first" processor to become idle. It blocks -in select instead of pause. If there are no idle processors, I/O is -polled in the thread timer interrupt handler as usual. Thus, when a -processor "finishes" a thread (i.e. the thread blocks, suspends or -dies), it consults the runnable queue. If the queue is empty, the -processor attempts to become the "I/O waiter". If there already is -one, it goes to idle. +in test-select-registry instead of smp-idle. If there are no idle +processors, I/O is polled (nonblocking) in the thread timer interrupt +handler as usual. Thus, when a processor "finishes" a thread +(i.e. the thread blocks, suspends or dies), it consults the runnable +queue. If the queue is empty, the processor attempts to become the +"I/O waiter". If there already is one, it goes to idle. When I/O arrives, the I/O waiter runs with it, but first wakes an idle processor (with a timer interrupt) if any. The awoken likely will become the next I/O waiter, though another processor could finish a thread or get a timer interrupt and become I/O waiter first. Ensuring -there is one I/O waiter simplifies updates to the system's select- +there is one I/O waiter simplifies updates to the system's io- registry. All of the logic for scheduling threads and managing processors is @@ -55,9 +55,9 @@ data structures sane. A separate mutex, the state_mutex, is used by the garbage collector to make processor state changes atomic. Two condition variables, "ready" and "finished", are used with the state_mutex to cause the GC processor to wait for the others to get -ready (export thread-local state) and for the others to wait until the -GC processor is finished (so they can import their thread-local state -and continue). +ready (export pthread-local state) and for the others to wait until +the GC processor is finished (so they can import their pthread-local +state and continue). ** Creating Processors @@ -68,13 +68,13 @@ GC cannot start by signaling any new processors. Instead the new processors START in the gc-wait state via Scheme's smp-pause primitive. -The main pthread avoids signaling new processors by waiting (on the -"ready" signal) for all processors to reach the gc-wait state. When -ready, the main pthread runs the interpreter to bootstrap or load a -band. The waiting processors are blocked until the finished condition -is signaled by the primitive GC daemon. By that point, a bootstrap or -band restore will have initialized the interrupt handlers in the fixed -objects vector. +The main pthread avoids signaling uninitialized processors by waiting +(on the "ready" signal) for all processors to reach the gc-wait state. +When ready, the main pthread runs the interpreter to bootstrap or load +a band. The waiting processors are blocked until the finished +condition is signaled by the primitive GC daemon. By that point, a +bootstrap or band restore will have initialized the interrupt handlers +in the fixed objects vector. A processor continues from smp-pause by "restarting" a different primitive -- smp-idle. In smp-idle, they wait for a timer interrupt.