equal
deleted
inserted
replaced
1 /* |
1 /* |
2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
101 |
101 |
102 // Tunables ... |
102 // Tunables ... |
103 // The knob* variables are effectively final. Once set they should |
103 // The knob* variables are effectively final. Once set they should |
104 // never be modified hence. Consider using __read_mostly with GCC. |
104 // never be modified hence. Consider using __read_mostly with GCC. |
105 |
105 |
|
106 int ObjectMonitor::Knob_ExitRelease = 0; |
106 int ObjectMonitor::Knob_Verbose = 0; |
107 int ObjectMonitor::Knob_Verbose = 0; |
107 int ObjectMonitor::Knob_VerifyInUse = 0; |
108 int ObjectMonitor::Knob_VerifyInUse = 0; |
|
109 int ObjectMonitor::Knob_VerifyMatch = 0; |
108 int ObjectMonitor::Knob_SpinLimit = 5000; // derived by an external tool - |
110 int ObjectMonitor::Knob_SpinLimit = 5000; // derived by an external tool - |
109 static int Knob_LogSpins = 0; // enable jvmstat tally for spins |
111 static int Knob_LogSpins = 0; // enable jvmstat tally for spins |
110 static int Knob_HandOff = 0; |
112 static int Knob_HandOff = 0; |
111 static int Knob_ReportSettings = 0; |
113 static int Knob_ReportSettings = 0; |
112 |
114 |
248 // * See also http://blogs.sun.com/dave |
250 // * See also http://blogs.sun.com/dave |
249 |
251 |
250 |
252 |
251 // ----------------------------------------------------------------------------- |
253 // ----------------------------------------------------------------------------- |
252 // Enter support |
254 // Enter support |
253 |
|
254 bool ObjectMonitor::try_enter(Thread* THREAD) { |
|
255 if (THREAD != _owner) { |
|
256 if (THREAD->is_lock_owned ((address)_owner)) { |
|
257 assert(_recursions == 0, "internal state error"); |
|
258 _owner = THREAD; |
|
259 _recursions = 1; |
|
260 return true; |
|
261 } |
|
262 if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) { |
|
263 return false; |
|
264 } |
|
265 return true; |
|
266 } else { |
|
267 _recursions++; |
|
268 return true; |
|
269 } |
|
270 } |
|
271 |
255 |
272 void NOINLINE ObjectMonitor::enter(TRAPS) { |
256 void NOINLINE ObjectMonitor::enter(TRAPS) { |
273 // The following code is ordered to check the most common cases first |
257 // The following code is ordered to check the most common cases first |
274 // and to reduce RTS->RTO cache line upgrades on SPARC and IA32 processors. |
258 // and to reduce RTS->RTO cache line upgrades on SPARC and IA32 processors. |
275 Thread * const Self = THREAD; |
259 Thread * const Self = THREAD; |
2270 JavaThread *jt = (JavaThread *)this->_thread; |
2254 JavaThread *jt = (JavaThread *)this->_thread; |
2271 JavaThreadBlockedOnMonitorEnterState::wait_reenter_end(jt, _active); |
2255 JavaThreadBlockedOnMonitorEnterState::wait_reenter_end(jt, _active); |
2272 } |
2256 } |
2273 |
2257 |
2274 inline void ObjectMonitor::AddWaiter(ObjectWaiter* node) { |
2258 inline void ObjectMonitor::AddWaiter(ObjectWaiter* node) { |
2275 assert(node != NULL, "should not dequeue NULL node"); |
2259 assert(node != NULL, "should not add NULL node"); |
2276 assert(node->_prev == NULL, "node already in list"); |
2260 assert(node->_prev == NULL, "node already in list"); |
2277 assert(node->_next == NULL, "node already in list"); |
2261 assert(node->_next == NULL, "node already in list"); |
2278 // put node at end of queue (circular doubly linked list) |
2262 // put node at end of queue (circular doubly linked list) |
2279 if (_WaitSet == NULL) { |
2263 if (_WaitSet == NULL) { |
2280 _WaitSet = node; |
2264 _WaitSet = node; |
2405 |
2389 |
2406 static int kvGetInt(char * kvList, const char * Key, int Default) { |
2390 static int kvGetInt(char * kvList, const char * Key, int Default) { |
2407 char * v = kvGet(kvList, Key); |
2391 char * v = kvGet(kvList, Key); |
2408 int rslt = v ? ::strtol(v, NULL, 0) : Default; |
2392 int rslt = v ? ::strtol(v, NULL, 0) : Default; |
2409 if (Knob_ReportSettings && v != NULL) { |
2393 if (Knob_ReportSettings && v != NULL) { |
2410 ::printf (" SyncKnob: %s %d(%d)\n", Key, rslt, Default) ; |
2394 tty->print_cr("INFO: SyncKnob: %s %d(%d)", Key, rslt, Default) ; |
2411 ::fflush(stdout); |
2395 tty->flush(); |
2412 } |
2396 } |
2413 return rslt; |
2397 return rslt; |
2414 } |
2398 } |
2415 |
2399 |
2416 void ObjectMonitor::DeferredInitialize() { |
2400 void ObjectMonitor::DeferredInitialize() { |
2440 if (*p == ':') *p = 0; |
2424 if (*p == ':') *p = 0; |
2441 } |
2425 } |
2442 |
2426 |
2443 #define SETKNOB(x) { Knob_##x = kvGetInt(knobs, #x, Knob_##x); } |
2427 #define SETKNOB(x) { Knob_##x = kvGetInt(knobs, #x, Knob_##x); } |
2444 SETKNOB(ReportSettings); |
2428 SETKNOB(ReportSettings); |
|
2429 SETKNOB(ExitRelease); |
2445 SETKNOB(Verbose); |
2430 SETKNOB(Verbose); |
2446 SETKNOB(VerifyInUse); |
2431 SETKNOB(VerifyInUse); |
|
2432 SETKNOB(VerifyMatch); |
2447 SETKNOB(FixedSpin); |
2433 SETKNOB(FixedSpin); |
2448 SETKNOB(SpinLimit); |
2434 SETKNOB(SpinLimit); |
2449 SETKNOB(SpinBase); |
2435 SETKNOB(SpinBase); |
2450 SETKNOB(SpinBackOff); |
2436 SETKNOB(SpinBackOff); |
2451 SETKNOB(CASPenalty); |
2437 SETKNOB(CASPenalty); |
2475 sanity_checks(); |
2461 sanity_checks(); |
2476 } |
2462 } |
2477 |
2463 |
2478 if (os::is_MP()) { |
2464 if (os::is_MP()) { |
2479 BackOffMask = (1 << Knob_SpinBackOff) - 1; |
2465 BackOffMask = (1 << Knob_SpinBackOff) - 1; |
2480 if (Knob_ReportSettings) ::printf("BackOffMask=%X\n", BackOffMask); |
2466 if (Knob_ReportSettings) { |
|
2467 tty->print_cr("INFO: BackOffMask=0x%X", BackOffMask); |
|
2468 } |
2481 // CONSIDER: BackOffMask = ROUNDUP_NEXT_POWER2 (ncpus-1) |
2469 // CONSIDER: BackOffMask = ROUNDUP_NEXT_POWER2 (ncpus-1) |
2482 } else { |
2470 } else { |
2483 Knob_SpinLimit = 0; |
2471 Knob_SpinLimit = 0; |
2484 Knob_SpinBase = 0; |
2472 Knob_SpinBase = 0; |
2485 Knob_PreSpin = 0; |
2473 Knob_PreSpin = 0; |