1/*
2 * Copyright (c) 2012, 2019, 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 "jfr/recorder/jfrRecorder.hpp"
27#include "jfr/recorder/service/jfrPostBox.hpp"
28#include "jfr/recorder/service/jfrRecorderService.hpp"
29#include "jfr/recorder/service/jfrRecorderThread.hpp"
30#include "logging/log.hpp"
31#include "runtime/mutexLocker.hpp"
32#include "runtime/thread.inline.hpp"
33
34//
35// Entry point for "JFR Recorder Thread" message loop.
36// The recorder thread executes service requests collected from the message system.
37//
38void recorderthread_entry(JavaThread* thread, Thread* unused) {
39 assert(thread != NULL, "invariant");
40 #define START (msgs & (MSGBIT(MSG_START)))
41 #define SHUTDOWN (msgs & MSGBIT(MSG_SHUTDOWN))
42 #define ROTATE (msgs & (MSGBIT(MSG_ROTATE)|MSGBIT(MSG_STOP)))
43 #define PROCESS_FULL_BUFFERS (msgs & (MSGBIT(MSG_ROTATE)|MSGBIT(MSG_STOP)|MSGBIT(MSG_FULLBUFFER)))
44 #define SCAVENGE (msgs & (MSGBIT(MSG_DEADBUFFER)))
45
46 JfrPostBox& post_box = JfrRecorderThread::post_box();
47 log_debug(jfr, system)("Recorder thread STARTED");
48
49 {
50 bool done = false;
51 int msgs = 0;
52 JfrRecorderService service;
53 MutexLocker msg_lock(JfrMsg_lock);
54
55 // JFR MESSAGE LOOP PROCESSING - BEGIN
56 while (!done) {
57 if (post_box.is_empty()) {
58 JfrMsg_lock->wait();
59 }
60 msgs = post_box.collect();
61 JfrMsg_lock->unlock();
62 if (PROCESS_FULL_BUFFERS) {
63 service.process_full_buffers();
64 }
65 if (SCAVENGE) {
66 service.scavenge();
67 }
68 // Check amount of data written to chunk already
69 // if it warrants asking for a new chunk
70 service.evaluate_chunk_size_for_rotation();
71 if (START) {
72 service.start();
73 } else if (ROTATE) {
74 service.rotate(msgs);
75 }
76 JfrMsg_lock->lock();
77 post_box.notify_waiters();
78 if (SHUTDOWN) {
79 log_debug(jfr, system)("Request to STOP recorder");
80 done = true;
81 }
82 } // JFR MESSAGE LOOP PROCESSING - END
83
84 } // JfrMsg_lock scope
85
86 assert(!JfrMsg_lock->owned_by_self(), "invariant");
87 post_box.notify_collection_stop();
88 JfrRecorder::on_recorder_thread_exit();
89
90 #undef START
91 #undef SHUTDOWN
92 #undef ROTATE
93 #undef PROCESS_FULL_BUFFERS
94 #undef SCAVENGE
95}
96