- Loading...
...
ObjectMonitor T-deflate
T-enter +-----------------------+ --------------------------------------------
---------------------- | owner=DEFLATER_MARKER | deflate_monitor_using_JT() {
owner<owner contendedis contended> | contentions=0 | cmpxchg(DEFLATER_MARKER, &owner, NULL)
atomic inc contentions +-----------------------+ :
prev = cmpxchg(-max_jint, &contentions, 0)
...
ObjectMonitor T-deflate
T-enter +-----------------------+ --------------------------------------------
------------------------------- | owner=DEFLATER_MARKER | deflate_monitor_using_JT() {
owner<owner contended is contended> | contentions=-max_jint | cmpxchg(DEFLATER_MARKER, &owner, NULL)
atomic inc contentions +-----------------------+ :
if (contentions <= 0 && prev = cmpxchg(-max_jint, &contentions, 0)
owner == DEFLATER_MARKER) { if (prev == 0 &&
restore obj header owner == DEFLATER_MARKER) {
retry enter restore obj header
} finish the deflation
}
...
ObjectMonitor T-deflate
T-enter +-----------------------+ --------------------------------------------
------------------------------- | owner=DEFLATER_MARKER | deflate_monitor_using_JT() {
<owner owneris contended contended> | contentions=1 | cmpxchg(DEFLATER_MARKER, &owner, NULL)
atomic inc contentions +-----------------------+ :
if (contentions <= 0 && prev = cmpxchg(-max_jint, &contentions, 0)
owner == DEFLATER_MARKER) { if (prev == 0 &&
} else { owner == DEFLATER_MARKER) {
do contended } else {
enter work cmpxchg(NULL, &owner, DEFLATER_MARKER)
...
ObjectMonitor T-deflate
T-enter +-------------------------+ ------------------------------------------
------------------------------------------ | owner=DEFLATER_MARKER | deflate_monitor_using_JT() {
owner<owner contended is contended> | contentions=1 | cmpxchg(DEFLATER_MARKER, &owner, NULL)
atomic inc contentions +-------------------------+ 1> :
1> if (contentions <= 0 && || 2> : <thread_stalls>
owner == DEFLATER_MARKER) { \/ :
} else { +-------------------------+ :
EnterI() | owner=Self/T-enter | :
cmpxchg(Self, &owner, DEFLATER_MARKER) | contentions=0 | : <thread_resumes>
atomic dec contentions +-------------------------+ prev = cmpxchg(-max_jint, &contentions, 0)
2> } || if (prev == 0 &&
// finished with enter \/ owner == DEFLATER_MARKER) {
3> : <does app work> +-------------------------+ } else {
exit() monitor | owner=Self/T-enter|NULL | cmpxchg(NULL, &owner, DEFLATER_MARKER)
owner = NULL | contentions=0 | atomic add max_jint to contentions
+-------------------------+ 3> bailout on deflation
}
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.
This subsection is pure theory right now. I don't have a failing test case that illustrates this race result.
After working out the bug described in the "T-deflate and T-hash Both Lose" subsection below, it is time to take a closer look at the T-enter versus T-deflate race. For analysis of this race to make sense, the ref_count field has to be introduced in this subsection instead of in the "Hashcodes and Object Header Interference" section below.
ObjectMonitor T-deflate
T-enter +-------------------------+ -----------------------------------------------
------------------------------------------ | owner=DEFLATER_MARKER | deflate_monitor_using_JT() {
ref_count inc by ObjectMonitorHandle | contentions=0 | cmpxchg(DEFLATER_MARKER, &owner, NULL)
<owner is contended> | ref_count=1 | if (waiters != 0 || ref_count != 0) {
1> atomic inc contentions +-------------------------+ }
if (contentions <= 0 && || 1> prev = cmpxchg(-max_jint, &contentions, 0)
owner == DEFLATER_MARKER) { \/ 2> if (prev == 0 &&
2> restore obj header +-------------------------+ owner == DEFLATER_MARKER &&
retry enter | owner=DEFLATER_MARKER | cmpxchg(-max_jint, &ref_count, 0) == 0) {
} | contentions=-max_jint | restore obj header
| ref_count=1 | finish the deflation
+-------------------------+ } else {
cmpxchg(NULL, &owner, DEFLATER_MARKER)
atomic add max_jint to contentions
bailout on deflation
}
I have to look at this new theory with fresh eyes, but if it holds together, then T-enter's "contentions <= 0 && owner == DEFLATER_MARKER" check will need to be changed to "contentions <= 0 && owner == DEFLATER_MARKER && ref_count <= 0" as was done for save_om_ptr().
...