< 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
@@ -108,11 +108,10 @@
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_MoveNotifyee = 2; // notify() - disposition of notifyee
static int Knob_QMode = 0; // EntryList-cxq policy - queue discipline
static volatile int InitDone = 0;
// -----------------------------------------------------------------------------
// Theory of operations -- Monitors lists, thread residency, etc:
@@ -1521,61 +1520,34 @@
// If the lock is cool (cxq == null && succ == null) and we're on an MP system
// then instead of transferring a thread from the WaitSet to the EntryList
// we might just dequeue a thread from the WaitSet and directly unpark() it.
void ObjectMonitor::INotify(Thread * Self) {
- const int policy = Knob_MoveNotifyee;
-
Thread::SpinAcquire(&_WaitSetLock, "WaitSet - notify");
ObjectWaiter * iterator = DequeueWaiter();
if (iterator != NULL) {
guarantee(iterator->TState == ObjectWaiter::TS_WAIT, "invariant");
guarantee(iterator->_notified == 0, "invariant");
// Disposition - what might we do with iterator ?
// a. add it directly to the EntryList - either tail (policy == 1)
// or head (policy == 0).
// b. push it onto the front of the _cxq (policy == 2).
// For now we use (b).
- if (policy != 4) {
+
iterator->TState = ObjectWaiter::TS_ENTER;
- }
+
iterator->_notified = 1;
iterator->_notifier_tid = JFR_THREAD_ID(Self);
ObjectWaiter * list = _EntryList;
if (list != NULL) {
assert(list->_prev == NULL, "invariant");
assert(list->TState == ObjectWaiter::TS_ENTER, "invariant");
assert(list != iterator, "invariant");
}
- if (policy == 0) { // prepend to EntryList
- if (list == NULL) {
- iterator->_next = iterator->_prev = NULL;
- _EntryList = iterator;
- } else {
- list->_prev = iterator;
- iterator->_next = list;
- iterator->_prev = NULL;
- _EntryList = iterator;
- }
- } else if (policy == 1) { // append to EntryList
- if (list == NULL) {
- iterator->_next = iterator->_prev = NULL;
- _EntryList = iterator;
- } else {
- // CONSIDER: finding the tail currently requires a linear-time walk of
- // the EntryList. We can make tail access constant-time by converting to
- // a CDLL instead of using our current DLL.
- ObjectWaiter * tail;
- for (tail = list; tail->_next != NULL; tail = tail->_next) {}
- assert(tail != NULL && tail->_next == NULL, "invariant");
- tail->_next = iterator;
- iterator->_prev = tail;
- iterator->_next = NULL;
- }
- } else if (policy == 2) { // prepend to cxq
+ // prepend to cxq
if (list == NULL) {
iterator->_next = iterator->_prev = NULL;
_EntryList = iterator;
} else {
iterator->TState = ObjectWaiter::TS_CXQ;
@@ -1585,46 +1557,21 @@
if (Atomic::cmpxchg(iterator, &_cxq, front) == front) {
break;
}
}
}
- } else if (policy == 3) { // append to cxq
- iterator->TState = ObjectWaiter::TS_CXQ;
- for (;;) {
- ObjectWaiter * tail = _cxq;
- if (tail == NULL) {
- iterator->_next = NULL;
- if (Atomic::replace_if_null(iterator, &_cxq)) {
- break;
- }
- } else {
- while (tail->_next != NULL) tail = tail->_next;
- tail->_next = iterator;
- iterator->_prev = tail;
- iterator->_next = NULL;
- break;
- }
- }
- } else {
- ParkEvent * ev = iterator->_event;
- iterator->TState = ObjectWaiter::TS_RUN;
- OrderAccess::fence();
- ev->unpark();
- }
// _WaitSetLock protects the wait queue, not the EntryList. We could
// move the add-to-EntryList operation, above, outside the critical section
// protected by _WaitSetLock. In practice that's not useful. With the
// exception of wait() timeouts and interrupts the monitor owner
// is the only thread that grabs _WaitSetLock. There's almost no contention
// on _WaitSetLock so it's not profitable to reduce the length of the
// critical section.
- if (policy < 4) {
iterator->wait_reenter_begin(this);
}
- }
Thread::SpinRelease(&_WaitSetLock);
}
// Consider: a not-uncommon synchronization bug is to use notify() when
// notifyAll() is more appropriate, potentially resulting in stranded
< prev index next >