Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Add "T-enter Wins By A-B-A" section.

...

                               ObjectMonitor              T-deflate
    T-enter                    +-----------------------+  --------------------------------------
    ----------------           | owner=DEFLATER_MARKER |  cmpxchg(DEFLATER_MARKER, &owner, NULL)
    owner contended            | count=-max_jint       |  :
    atomic inc count           +-----------------------+  prev = cmpxchg(-max_jint, &count, 0)
    if (count <= 0 && owner                               if (prev == 0 &&
        == DEFLATER_MARKER) {                                 owner == DEFLATER_MARKER) {
      restore header                                        restore header
      retry enter                                           finish the deflation
    }                                                     }
    • This diagram starts after "Racing Threads".
    • T-enter and T-deflate both observe owner == DEFLATER_MARKER and a negative count field.
    • T-enter has lost the race and it retries.
    • T-deflate finishes deflation of the ObjectMonitor

...

                      ObjectMonitor              T-deflate
    T-enter           +-----------------------+  --------------------------------------
    ----------------  | owner=DEFLATER_MARKER |  cmpxchg(DEFLATER_MARKER, &owner, NULL)
    owner contended   | count=1               |  :
    atomic inc count  +-----------------------+  prev = cmpxchg(-max_jint, &count, 0)
    if (count > 0)                               if (prev != 0 ||
      do contended                                   owner != DEFLATER_MARKER)
      enter work                                 bailout on deflation
    • This diagram starts after "Racing Threads".
    • T-enter and T-deflate both observe a count field > 0.
    • T-enter has won the race and it proceeds with the normal contended enter work.
    • T-deflate detects that it has lost the race and bails out on deflating the ObjectMonitor.
    • In this example, T-deflate never reaches the DEFLATER_MARKER check.

T-enter Wins By A-B-A

                                                ObjectMonitor                T-deflate
    T-enter           +-------------------------+  --------------------------------------
    ------------------------------------------ | owner=DEFLATER_MARKER |  cmpxchg(DEFLATER_MARKER, &owner, NULL)
    owner contended   | count=1                |  : <thread_stalls>
    atomic inc count  +-------------------------+  :
    if (count > 0)                               || :
      EnterI()                               \/ :
      cmpxchg(Self, &owner, DEFLATER_MARKER)  +-------------------------+ :
atomic dec count | owner=Self/T-enter | : <thread_resumes>
} | count=0 | prev = cmpxchg(-max_jint, &count, 0)
// finished with enter +-------------------------+ if (prev != 0 ||
: <does app work> || owner != DEFLATER_MARKER)
exit() monitor \/ bailout on deflation
owner = NULL +-------------------------+
| owner=Self/T-enter|NULL |
| count=-max_jint |
+-------------------------+
    • This diagram starts after "Racing Threads".
    • T-enter observes a count field > 0.
    • T-deflate stalls after setting the owner field to DEFLATER_MARKER.
    • T-enter has won the race and calls EnterI() to do the contended enter work.
      • EnterI() observes owner == DEFLATER_MARKER and uses cmpxchg() to set the owner field to Self/T-enter.
      • T-enter decrements the count field because it is no longer contending for the monitor; it owns the monitor.
    • The second ObjectMonitor box is showing the fields at this point.
    • T-deflate resumes, sets the count field to -max_jint, and passes the first part of the bailout expression because "prev == 0".
    • T-deflate observes that "owner != DEFLATE_MARKER" and bails out on deflation.
      • Depending on when T-deflate resumes after the stall, it will see "owner == T-enter" or "owner == NULL".
      • Both of those values will cause deflation to bailout.
    • The third ObjectMonitor box is showing the fields at this point.
    • If the T-enter thread has managed to enter but not exit the monitor during the T-deflate stall, then our owner field A-B-A transition is:
          NULL → DEFLATE_MARKER → Self/T-enter
      so we really have A1-B-A2, but the A-B-A principal still holds.

    • If the T-enter thread has managed to enter and exit the monitor during the T-deflate stall, then our owner field A-B-A transition is:
          NULL → DEFLATE_MARKER → Self/T-enter  → NULL
      so we really have A-B1-B2-A, but the A-B-A principal still holds.

An Example of Object Header Interference

...