1 /*
2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
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
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.hpp"
27 #include "classfile/vmSymbols.hpp"
28 #include "memory/universe.hpp"
29 #include "runtime/interfaceSupport.inline.hpp"
30 #include "runtime/java.hpp"
31 #include "runtime/javaCalls.hpp"
32 #include "runtime/monitorDeflationThread.hpp"
33 #include "runtime/mutexLocker.hpp"
34 
35 MonitorDeflationThread* MonitorDeflationThread::_instance = NULL;
36 
initialize()37 void MonitorDeflationThread::initialize() {
38   EXCEPTION_MARK;
39 
40   const char* name = "Monitor Deflation Thread";
41   Handle string = java_lang_String::create_from_str(name, CHECK);
42 
43   // Initialize thread_oop to put it into the system threadGroup
44   Handle thread_group (THREAD, Universe::system_thread_group());
45   Handle thread_oop = JavaCalls::construct_new_instance(
46                           SystemDictionary::Thread_klass(),
47                           vmSymbols::threadgroup_string_void_signature(),
48                           thread_group,
49                           string,
50                           CHECK);
51 
52   {
53     MutexLocker mu(THREAD, Threads_lock);
54     MonitorDeflationThread* thread =  new MonitorDeflationThread(&monitor_deflation_thread_entry);
55 
56     // At this point it may be possible that no osthread was created for the
57     // JavaThread due to lack of memory. We would have to throw an exception
58     // in that case. However, since this must work and we do not allow
59     // exceptions anyway, check and abort if this fails.
60     if (thread == NULL || thread->osthread() == NULL) {
61       vm_exit_during_initialization("java.lang.OutOfMemoryError",
62                                     os::native_thread_creation_failed_msg());
63     }
64 
65     java_lang_Thread::set_thread(thread_oop(), thread);
66     java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
67     java_lang_Thread::set_daemon(thread_oop());
68     thread->set_threadObj(thread_oop());
69     _instance = thread;
70 
71     Threads::add(thread);
72     Thread::start(thread);
73   }
74 }
75 
monitor_deflation_thread_entry(JavaThread * jt,TRAPS)76 void MonitorDeflationThread::monitor_deflation_thread_entry(JavaThread* jt, TRAPS) {
77   while (true) {
78     {
79       // Need state transition ThreadBlockInVM so that this thread
80       // will be handled by safepoint correctly when this thread is
81       // notified at a safepoint.
82 
83       // This ThreadBlockInVM object is not also considered to be
84       // suspend-equivalent because MonitorDeflationThread is not
85       // visible to external suspension.
86 
87       ThreadBlockInVM tbivm(jt);
88 
89       MonitorLocker ml(MonitorDeflation_lock, Mutex::_no_safepoint_check_flag);
90       while (!ObjectSynchronizer::is_async_deflation_needed()) {
91         // Wait until notified that there is some work to do.
92         // We wait for GuaranteedSafepointInterval so that
93         // is_async_deflation_needed() is checked at the same interval.
94         ml.wait(GuaranteedSafepointInterval);
95       }
96     }
97 
98     (void)ObjectSynchronizer::deflate_idle_monitors();
99   }
100 }
101