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