Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/logging/logAsyncWriter.hpp
40930 views
1
/*
2
* Copyright Amazon.com Inc. 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
#ifndef SHARE_LOGGING_LOGASYNCWRITER_HPP
25
#define SHARE_LOGGING_LOGASYNCWRITER_HPP
26
#include "logging/log.hpp"
27
#include "logging/logDecorations.hpp"
28
#include "logging/logFileOutput.hpp"
29
#include "logging/logMessageBuffer.hpp"
30
#include "memory/resourceArea.hpp"
31
#include "runtime/nonJavaThread.hpp"
32
#include "utilities/hashtable.hpp"
33
#include "utilities/linkedlist.hpp"
34
35
template <typename E, MEMFLAGS F>
36
class LinkedListDeque : private LinkedListImpl<E, ResourceObj::C_HEAP, F> {
37
private:
38
LinkedListNode<E>* _tail;
39
size_t _size;
40
41
public:
42
LinkedListDeque() : _tail(NULL), _size(0) {}
43
void push_back(const E& e) {
44
if (!_tail) {
45
_tail = this->add(e);
46
} else {
47
_tail = this->insert_after(e, _tail);
48
}
49
50
++_size;
51
}
52
53
// pop all elements to logs.
54
void pop_all(LinkedList<E>* logs) {
55
logs->move(static_cast<LinkedList<E>* >(this));
56
_tail = NULL;
57
_size = 0;
58
}
59
60
void pop_all(LinkedListDeque<E, F>* logs) {
61
logs->_size = _size;
62
logs->_tail = _tail;
63
pop_all(static_cast<LinkedList<E>* >(logs));
64
}
65
66
void pop_front() {
67
LinkedListNode<E>* h = this->unlink_head();
68
if (h == _tail) {
69
_tail = NULL;
70
}
71
72
if (h != NULL) {
73
--_size;
74
this->delete_node(h);
75
}
76
}
77
78
size_t size() const { return _size; }
79
80
const E* front() const {
81
return this->_head == NULL ? NULL : this->_head->peek();
82
}
83
84
const E* back() const {
85
return _tail == NULL ? NULL : _tail->peek();
86
}
87
88
LinkedListNode<E>* head() const {
89
return this->_head;
90
}
91
};
92
93
class AsyncLogMessage {
94
LogFileOutput& _output;
95
const LogDecorations _decorations;
96
char* _message;
97
98
public:
99
AsyncLogMessage(LogFileOutput& output, const LogDecorations& decorations, char* msg)
100
: _output(output), _decorations(decorations), _message(msg) {}
101
102
// placeholder for LinkedListImpl.
103
bool equals(const AsyncLogMessage& o) const { return false; }
104
105
LogFileOutput* output() const { return &_output; }
106
const LogDecorations& decorations() const { return _decorations; }
107
char* message() const { return _message; }
108
};
109
110
typedef LinkedListDeque<AsyncLogMessage, mtLogging> AsyncLogBuffer;
111
typedef KVHashtable<LogFileOutput*, uint32_t, mtLogging> AsyncLogMap;
112
113
//
114
// ASYNC LOGGING SUPPORT
115
//
116
// Summary:
117
// Async Logging is working on the basis of singleton AsyncLogWriter, which manages an intermediate buffer and a flushing thread.
118
//
119
// Interface:
120
//
121
// initialize() is called once when JVM is initialized. It creates and initializes the singleton instance of AsyncLogWriter.
122
// Once async logging is established, there's no way to turn it off.
123
//
124
// instance() is MT-safe and returns the pointer of the singleton instance if and only if async logging is enabled and has well
125
// initialized. Clients can use its return value to determine async logging is established or not.
126
//
127
// The basic operation of AsyncLogWriter is enqueue(). 2 overloading versions of it are provided to match LogOutput::write().
128
// They are both MT-safe and non-blocking. Derived classes of LogOutput can invoke the corresponding enqueue() in write() and
129
// return 0. AsyncLogWriter is responsible of copying neccessary data.
130
//
131
// The static member function flush() is designated to flush out all pending messages when JVM is terminating.
132
// In normal JVM termination, flush() is invoked in LogConfiguration::finalize(). flush() is MT-safe and can be invoked arbitrary
133
// times. It is no-op if async logging is not established.
134
//
135
class AsyncLogWriter : public NonJavaThread {
136
static AsyncLogWriter* _instance;
137
// _sem is a semaphore whose value denotes how many messages have been enqueued.
138
// It decreases in AsyncLogWriter::run()
139
static Semaphore _sem;
140
// A lock of IO
141
static Semaphore _io_sem;
142
143
volatile bool _initialized;
144
AsyncLogMap _stats; // statistics for dropped messages
145
AsyncLogBuffer _buffer;
146
147
// The memory use of each AsyncLogMessage (payload) consists of itself and a variable-length c-str message.
148
// A regular logging message is smaller than vwrite_buffer_size, which is defined in logtagset.cpp
149
const size_t _buffer_max_size = {AsyncLogBufferSize / (sizeof(AsyncLogMessage) + vwrite_buffer_size)};
150
151
AsyncLogWriter();
152
void enqueue_locked(const AsyncLogMessage& msg);
153
void write();
154
void run() override;
155
void pre_run() override {
156
NonJavaThread::pre_run();
157
log_debug(logging, thread)("starting AsyncLog Thread tid = " INTX_FORMAT, os::current_thread_id());
158
}
159
char* name() const override { return (char*)"AsyncLog Thread"; }
160
bool is_Named_thread() const override { return true; }
161
void print_on(outputStream* st) const override {
162
st->print("\"%s\" ", name());
163
Thread::print_on(st);
164
st->cr();
165
}
166
167
public:
168
void enqueue(LogFileOutput& output, const LogDecorations& decorations, const char* msg);
169
void enqueue(LogFileOutput& output, LogMessageBuffer::Iterator msg_iterator);
170
171
static AsyncLogWriter* instance();
172
static void initialize();
173
static void flush();
174
};
175
176
#endif // SHARE_LOGGING_LOGASYNCWRITER_HPP
177
178