JDK-6441899 : os::is_MP() does not return the right value the first time called
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2006-06-21
  • Updated: 2012-10-08
  • Resolved: 2006-11-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u4Fixed 7Fixed hs10Fixed
In the hotspot code, os::is_MP is called to detect whether the system contains multiple processor or not. It is called by Atomic::add in JNI_CreateJavaVM for the first time. However, that time, os::init() hasn't been called, so processor count is 0, so os::is_MP always returns false when it is called for the first time. As a result, Atomic::add won't be thread safe.

EVALUATION Note that this change added an implicit requirement that all Atomic::xchg implementations need to provide MP-safe atomicity without being able to check os::is_MP(). For systems that rely on the StubGenerator to generate the atomic ops based on the available instructions, this requirement is not met - the first time this gets used no generate function is available and we fall-back to plain non-atomic code. So, for example, on Windows 32-bit the Atomic::xchg used during JNI_CreateJavaVM is not actually atomic.

EVALUATION Look at the implementation of JNI_CreateJavaVM, it calls Atomic::add and Atomic::xchange. The Atomic::add call will call os::is_MP to find out whether the underlying system has more than 1 processors. Atomic::xchange doesn't do that however. Semantically, Atomic::xchange should be multi-processor safe call. So to prevent mutiple threads from creating JVM simultaneously, Atomic::xchange(1, &cm_created) will be suffcient. I have a webrev at http://javaweb.sfbay/~xl116366/webrev/6441899 where I eliminated a premature Atomic::add call and added the assertion to os::is_MP implementation so it won't return wrong information to the caller.

SUGGESTED FIX David Holmes suggested two ways to fix this problem: >> From Holmes: One ugly fix would be to provide Atomic::add, Atomic:xchg and Atomic:dec variants that always assume they are on MP and so avoid the test. They'd only be called from this code. Another fix would be to replace the use of atomics with raw native "mutexes" - I can understand why our internal mutexes won't work at that stage but native ones will. The second fix sounds good to me.

EVALUATION Commit it to dolphin. See "suggested fix" for details about the fix.