Author: Armin Rigo <[email protected]>
Branch: extradoc
Changeset: r4054:79baef447541
Date: 2012-01-26 21:14 +0100
http://bitbucket.org/pypy/extradoc/changeset/79baef447541/

Log:    More.

diff --git a/planning/stm.txt b/planning/stm.txt
--- a/planning/stm.txt
+++ b/planning/stm.txt
@@ -20,7 +20,7 @@
 access to a global object, we need to make a whole copy of it into our
 nursery.
 
-The RPython program should have at least one hint: "force for writing",
+The RPython program should have at least one hint: "force local copy",
 which is like writing to an object in the sense that it forces a local
 copy.
 
@@ -28,16 +28,16 @@
 are known to be local.  It lets us avoid the run-time check.  That's
 useful for all freshly malloc'ed objects, which we know are always
 local; and that's useful for special cases like the PyFrames, on which
-we would use the "force for writing" hint before running the
+we would use the "force local copy" hint before running the
 interpreter.  In both cases the result is: no STM code is needed any
 more.
 
-When a transaction commits, we do a "minor collection"-like process: we
-move all surviving objects from the nursery to the global area, either
-as new objects, or as overwrites of their previous version.  So there is
-one "minor collection" at the end of every transaction.  Unlike the
-minor collections in other GCs, this one occurs at a well-defined time,
-with no stack roots to scan.
+When a transaction commits, we do a "minor collection"-like process,
+called an "end-of-transaction collection": we move all surviving objects
+from the nursery to the global area, either as new objects, or as
+overwrites of their previous version.  Unlike the minor collections in
+other GCs, this one occurs at a well-defined time, with no stack roots
+to scan.
 
 Later we'll need to consider what occurs if a nursery grows too big
 while the transaction is still not finished.  Probably somehow run a
@@ -46,7 +46,8 @@
 Of course we also need to do from time to time a major collection.  We
 will need at some point some concurrency here, to be able to run the
 major collection in a random thread t but detecting changes done by the
-other threads overwriting objects during their own minor collections.
+other threads overwriting objects during their own end-of-transaction
+collections.
 
 
 GC flags
@@ -59,3 +60,87 @@
   * GC_WAS_COPIED  on a global object: it has at least one local copy
                    (then we need to look it up in some local dictionary)
                    on a local object: it comes from a global object
+
+  * and one complete word (for now?) for the version number, see below
+
+(Optimization: objects declared immutable don't need a version number.)
+
+
+stm_read
+--------
+
+The STM read operation is potentially a complex operation.  (That's why
+it's useful to remove it as much as possible.)
+
+stm_read(obj, offset) -> field value
+
+- If obj is not GC_GLOBAL, then read directly and be done.
+
+- Otherwise, if GC_WAS_COPIED, and if we find 'localobj' in this
+  thread's local dictionary, then read directly from 'localobj' and
+  be done.  (Ideally we should also use 'localobj' instead of 'obj'
+  in future references to this object, but unclear how.)
+
+- Otherwise, we need to do a global read.  This is a real STM read.
+  Done (on x86 [1]) by reading the version number, then the actual field,
+  then *again* the version number.  If the version number didn't change
+  and if it is not more recent than the transaction start, then the read
+  is accepted; otherwise not (we might retry or abort the transaction,
+  depending on cases).  And if the read is accepted then we need to
+  remember in a local list that we've read that object.
+
+
+stm_write
+---------
+
+- If obj is GC_GLOBAL, we need to find or make a local copy
+
+- Then we just perform the write.
+
+This means that stm_write could be implemented with a write barrier that
+returns potentially a copy of the object, and which is followed by a
+regular write to that copy.
+
+Note that "making a local copy" implies the same rules as stm_read: read
+the version number, copy all fields, then read *again* the version
+number [1].  If it didn't change, then we know that we got at least a
+consistent copy (i.e. nobody changed the object in the middle of us
+reading it).  If it is too recent, then we might have to abort.
+
+
+End-of-transaction collections
+------------------------------
+
+Start from the "roots" being all local copies of global objects.  (These
+are the only roots: if there are none, then it means we didn't write
+anything in any global object, so there is no new object that can
+survive.)  From the roots, scan and move all fresh new objects to the
+global area.  Add the GC_GLOBAL flag to them, of course.  Then we need,
+atomically (in the STM sense), to overwrite the old global objects with
+their local copies.  This is done by temporarily locking the global
+objects with a special value in their "version" field that will cause
+concurrent reads to spin-loop.
+
+
+Annotator support
+-----------------
+
+To get good performance, we should as much as possible use the
+'localobj' version of every object instead of the 'obj' one.  At least
+after a write barrier we should replace the local variable 'obj' with
+'localobj', and someone (the annotator? or later?) should propagate the
+fact that it is now a localobj that doesn't need special stm support
+any longer.  Similarly, all mallocs return a localobj.
+
+The "force local copy" hint should be used on PyFrame before the main
+interpreter loop, so that we can then be sure that all accesses to
+'frame' are to a local obj.  Ideally, we could even track which fields
+of a localobj are themselves localobjs.  This would be useful for
+'PyFrame.fastlocals_w': it should also be known to always be a localobj.
+
+
+notes
+-----
+
+[1] this relies on a property guaranteed so far by the x86, but not,
+    say, by PowerPCs.  (XXX find a reference again)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to