Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r62:4456f79692e9 Date: 2013-06-03 19:24 +0200 http://bitbucket.org/pypy/stmgc/changeset/4456f79692e9/
Log: More preparation. diff --git a/c3/doc-objects.txt b/c3/doc-objects.txt --- a/c3/doc-objects.txt +++ b/c3/doc-objects.txt @@ -8,19 +8,19 @@ Private freshly created \ Private, with backup - \ ^ \ ^ - \ / \ | - commit \ modify / commit | | - \ / | | modify - V / | | - Protected, no backup V | + \ ^ . | ^ + \ / . commit | | + commit \ modify / . | | + \ / . commit | | modify + V / V | | + Protected, no backup V | ^ ^ Protected, with backup / | gc | commit / `----------------' / / - Private copy of - a public obj + Private copy of (the dotted arrow is followed if the + a public obj protected backup copy was stolen) @@ -52,8 +52,8 @@ Public objects: - prebuilt object, never modified -1 - other public object, never modified GT -- outdated, has a protected copy ptr to prot/priv | 2 -- outdated, target stolen ptr to next public copy +- outdated, has a protected copy HANDLE to prot/priv copy +- outdated, target stolen ptr to a more recent public copy Public stubs: - from stealing: like outdated public objects @@ -62,6 +62,8 @@ PRN = Private revision number (negative odd number) GT = Global time (positive odd number) +HANDLE = Reference to a prot/priv copy and its thread + (positive even number, such that: handle % 4 == 2) @@ -71,6 +73,120 @@ - the PRN (private revision number): odd, negative, changes for every transaction that commits -- list of pairs (private converted from protected, backup copy) +- dict active_backup_copies = {private converted from protected: backup copy} -- dict {public obj: private copy} +- dict public_to_private = {public obj: private copy} + +- list read_set containing the objects in the read set, with possibly + some duplicates (but hopefully not too many) + + + +Kind of object copy distinguishing feature +------------------------------------------------------------------- + +Any private object h_revision == PRN +Private with a backup in active_backup_copies +Backup copy GCFLAG_BACKUP_COPY +Any public object GCFLAG_PUBLIC +Any protected object h_revision != PRN && !GCFLAG_PUBLIC +Stubs GCFLAG_STUB + +A public object that might \ +be key in public_to_private has additionally GCFLAG_PUBLIC_TO_PRIVATE + + + +Read barrier +----------------------------------------- + +Inline check: if P in read_barrier_cache, we don't call the slow path. +Slow path: + + if h_revision == PRN, just add P to read_barrier_cache and return + + if GCFLAG_PUBLIC: + + follow the chained list of h_revision's as long as they are + regular pointers + + if it ends with an odd revision number, check that it's older + than start_time; extend the start timestamp if not + + if it ends with a handle (L, Thread): + + if Thread is the current thread: set P = L + + else: do stealing and restart the read barrier + + if we land on a P in read_barrier_cache: return + + add P to 'read_set' + + add P to 'read_barrier_cache' and return + + +Handles are stored for example in a global list, and the actual handle +encodes an index in the list. Every entry in the list is a pointer to a +prot/priv object --- excepted once every N positions, where it is a +thread descriptor giving the thread to which all N-1 following pointers +belong. The pair (L, Thread) is thus `(list[H], list[H rounded down to +a multiple of N])`. + +Stealing of an object copy L is done with the "collection lock" of +the target Thread. The target would also acquire its own lock in +when doing some operations, like a minor collection, which can't +occur in parallel with stealing. + +Once we have the lock, stealing is: + + if the situation changed while we were waiting for the lock, return + + if L has got a backup copy, turn it public; + else L must be protected, and we make a public copy of it + + update the original P->h_revision to point directly to the new + public copy + + + +Write barrier +----------------------------------------- + +The write barrier works for both STM purposes and for GC purposes. + +Inline check: if h_revision == PRN && !GCFLAG_WRITE_BARRIER, we're done. +Slow path: + + R = read_barrier(P) # always do a full read_barrier first + + if h_revision == PRN: + + GC only: remove GCFLAG_WRITE_BARRIER, add R to the GC list of + modified old objects to trace at the next minor collection, + and return R + + elif GCFLAG_PUBLIC: + + add the flag GCFLAG_PUBLIC_TO_PRIVATE to R, if needed + + make a fresh private copy L of R, with h_revision == PRN + + add {R: L} in 'public_to_private' + + return L + + else: # protected object + + if h_revision is not a pointer: + + allocate a backup copy, and attach it to h_revision + + copy the object into the backup copy + + change h_revision to be PRN (i.e. turn private) + + if GCFLAG_WRITE_BARRIER: remove it, add R to the GC list of + modified old objects to trace at the next minor collection + + return R _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit