< prev index next >
src/hotspot/share/runtime/objectMonitor.cpp
Print this page
rev 51780 : imported patch syncknobs-00-base
rev 51781 : imported patch syncknobs-01-Knob_ReportSettings
rev 51782 : imported patch syncknobs-02-Knob_SpinBackOff
rev 51783 : imported patch syncknobs-03-BackOffMask
rev 51784 : imported patch syncknobs-04-Knob_ExitRelease
rev 51785 : imported patch syncknobs-05-Knob_InlineNotify
rev 51786 : imported patch syncknobs-06-Knob_Verbose
rev 51787 : imported patch syncknobs-07-Knob_VerifyInUse
rev 51788 : imported patch syncknobs-08-Knob_VerifyMatch
rev 51789 : imported patch syncknobs-09-Knob_SpinBase
rev 51790 : imported patch syncknobs-10-Knob_CASPenalty
rev 51791 : imported patch syncknobs-11-Knob_OXPenalty
rev 51792 : imported patch syncknobs-12-Knob_SpinSetSucc
rev 51793 : imported patch syncknobs-13-Knob_SpinEarly
rev 51794 : imported patch syncknobs-14-Knob_SuccEnabled
rev 51795 : imported patch syncknobs-15-Knob_SuccRestrict
rev 51796 : imported patch syncknobs-16-Knob_MaxSpinners
rev 51797 : imported patch syncknobs-17-Knob_SpinAfterFutile
rev 51798 : imported patch syncknobs-18-Knob_OState
rev 51799 : imported patch syncknobs-19-Knob_UsePause
rev 51800 : imported patch syncknobs-20-Knob_ExitPolicy
rev 51801 : imported patch syncknobs-21-Knob_ResetEvent
rev 51802 : imported patch syncknobs-22-Knob_FastHSSEC
rev 51803 : imported patch syncknobs-23-Knob_MoveNotifyee
rev 51804 : imported patch syncknobs-24-Knob_QMode
*** 108,118 ****
static int Knob_Penalty = 200; // spin failure penalty
static int Knob_Poverty = 1000;
static int Knob_FixedSpin = 0;
static int Knob_PreSpin = 10; // 20-100 likely better
- static int Knob_QMode = 0; // EntryList-cxq policy - queue discipline
static volatile int InitDone = 0;
// -----------------------------------------------------------------------------
// Theory of operations -- Monitors lists, thread residency, etc:
//
--- 108,117 ----
*** 958,1054 ****
}
guarantee(_owner == THREAD, "invariant");
ObjectWaiter * w = NULL;
- int QMode = Knob_QMode;
-
- if (QMode == 2 && _cxq != NULL) {
- // QMode == 2 : cxq has precedence over EntryList.
- // Try to directly wake a successor from the cxq.
- // If successful, the successor will need to unlink itself from cxq.
- w = _cxq;
- assert(w != NULL, "invariant");
- assert(w->TState == ObjectWaiter::TS_CXQ, "Invariant");
- ExitEpilog(Self, w);
- return;
- }
-
- if (QMode == 3 && _cxq != NULL) {
- // Aggressively drain cxq into EntryList at the first opportunity.
- // This policy ensure that recently-run threads live at the head of EntryList.
- // Drain _cxq into EntryList - bulk transfer.
- // First, detach _cxq.
- // The following loop is tantamount to: w = swap(&cxq, NULL)
- w = _cxq;
- for (;;) {
- assert(w != NULL, "Invariant");
- ObjectWaiter * u = Atomic::cmpxchg((ObjectWaiter*)NULL, &_cxq, w);
- if (u == w) break;
- w = u;
- }
- assert(w != NULL, "invariant");
-
- ObjectWaiter * q = NULL;
- ObjectWaiter * p;
- for (p = w; p != NULL; p = p->_next) {
- guarantee(p->TState == ObjectWaiter::TS_CXQ, "Invariant");
- p->TState = ObjectWaiter::TS_ENTER;
- p->_prev = q;
- q = p;
- }
-
- // Append the RATs to the EntryList
- // TODO: organize EntryList as a CDLL so we can locate the tail in constant-time.
- ObjectWaiter * Tail;
- for (Tail = _EntryList; Tail != NULL && Tail->_next != NULL;
- Tail = Tail->_next)
- /* empty */;
- if (Tail == NULL) {
- _EntryList = w;
- } else {
- Tail->_next = w;
- w->_prev = Tail;
- }
-
- // Fall thru into code that tries to wake a successor from EntryList
- }
-
- if (QMode == 4 && _cxq != NULL) {
- // Aggressively drain cxq into EntryList at the first opportunity.
- // This policy ensure that recently-run threads live at the head of EntryList.
-
- // Drain _cxq into EntryList - bulk transfer.
- // First, detach _cxq.
- // The following loop is tantamount to: w = swap(&cxq, NULL)
- w = _cxq;
- for (;;) {
- assert(w != NULL, "Invariant");
- ObjectWaiter * u = Atomic::cmpxchg((ObjectWaiter*)NULL, &_cxq, w);
- if (u == w) break;
- w = u;
- }
- assert(w != NULL, "invariant");
-
- ObjectWaiter * q = NULL;
- ObjectWaiter * p;
- for (p = w; p != NULL; p = p->_next) {
- guarantee(p->TState == ObjectWaiter::TS_CXQ, "Invariant");
- p->TState = ObjectWaiter::TS_ENTER;
- p->_prev = q;
- q = p;
- }
-
- // Prepend the RATs to the EntryList
- if (_EntryList != NULL) {
- q->_next = _EntryList;
- _EntryList->_prev = q;
- }
- _EntryList = w;
-
- // Fall thru into code that tries to wake a successor from EntryList
- }
w = _EntryList;
if (w != NULL) {
// I'd like to write: guarantee (w->_thread != Self).
// But in practice an exiting thread may find itself on the EntryList.
--- 957,966 ----
*** 1091,1129 ****
// and effectively lengthening the critical section.
// Invariant: s chases t chases u.
// TODO-FIXME: consider changing EntryList from a DLL to a CDLL so
// we have faster access to the tail.
- if (QMode == 1) {
- // QMode == 1 : drain cxq to EntryList, reversing order
- // We also reverse the order of the list.
- ObjectWaiter * s = NULL;
- ObjectWaiter * t = w;
- ObjectWaiter * u = NULL;
- while (t != NULL) {
- guarantee(t->TState == ObjectWaiter::TS_CXQ, "invariant");
- t->TState = ObjectWaiter::TS_ENTER;
- u = t->_next;
- t->_prev = u;
- t->_next = s;
- s = t;
- t = u;
- }
- _EntryList = s;
- assert(s != NULL, "invariant");
- } else {
- // QMode == 0 or QMode == 2
_EntryList = w;
ObjectWaiter * q = NULL;
ObjectWaiter * p;
for (p = w; p != NULL; p = p->_next) {
guarantee(p->TState == ObjectWaiter::TS_CXQ, "Invariant");
p->TState = ObjectWaiter::TS_ENTER;
p->_prev = q;
q = p;
}
- }
// In 1-0 mode we need: ST EntryList; MEMBAR #storestore; ST _owner = NULL
// The MEMBAR is satisfied by the release_store() operation in ExitEpilog().
// See if we can abdicate to a spinner instead of waking a thread.
--- 1003,1021 ----
< prev index next >