Path: blob/master/src/hotspot/share/logging/logAsyncWriter.hpp
64440 views
/*1* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/23#ifndef SHARE_LOGGING_LOGASYNCWRITER_HPP24#define SHARE_LOGGING_LOGASYNCWRITER_HPP25#include "logging/log.hpp"26#include "logging/logDecorations.hpp"27#include "logging/logFileOutput.hpp"28#include "logging/logMessageBuffer.hpp"29#include "memory/resourceArea.hpp"30#include "runtime/nonJavaThread.hpp"31#include "utilities/hashtable.hpp"32#include "utilities/linkedlist.hpp"3334template <typename E, MEMFLAGS F>35class LinkedListDeque : private LinkedListImpl<E, ResourceObj::C_HEAP, F> {36private:37LinkedListNode<E>* _tail;38size_t _size;3940public:41LinkedListDeque() : _tail(NULL), _size(0) {}42void push_back(const E& e) {43if (!_tail) {44_tail = this->add(e);45} else {46_tail = this->insert_after(e, _tail);47}4849++_size;50}5152// pop all elements to logs.53void pop_all(LinkedList<E>* logs) {54logs->move(static_cast<LinkedList<E>* >(this));55_tail = NULL;56_size = 0;57}5859void pop_all(LinkedListDeque<E, F>* logs) {60logs->_size = _size;61logs->_tail = _tail;62pop_all(static_cast<LinkedList<E>* >(logs));63}6465void pop_front() {66LinkedListNode<E>* h = this->unlink_head();67if (h == _tail) {68_tail = NULL;69}7071if (h != NULL) {72--_size;73this->delete_node(h);74}75}7677size_t size() const { return _size; }7879const E* front() const {80return this->_head == NULL ? NULL : this->_head->peek();81}8283const E* back() const {84return _tail == NULL ? NULL : _tail->peek();85}8687LinkedListNode<E>* head() const {88return this->_head;89}90};9192class AsyncLogMessage {93LogFileOutput* _output;94const LogDecorations _decorations;95char* _message;9697public:98AsyncLogMessage(LogFileOutput* output, const LogDecorations& decorations, char* msg)99: _output(output), _decorations(decorations), _message(msg) {}100101// placeholder for LinkedListImpl.102bool equals(const AsyncLogMessage& o) const { return false; }103104LogFileOutput* output() const { return _output; }105const LogDecorations& decorations() const { return _decorations; }106char* message() const { return _message; }107};108109typedef LinkedListDeque<AsyncLogMessage, mtLogging> AsyncLogBuffer;110typedef KVHashtable<LogFileOutput*, uint32_t, mtLogging> AsyncLogMap;111112//113// ASYNC LOGGING SUPPORT114//115// Summary:116// Async Logging is working on the basis of singleton AsyncLogWriter, which manages an intermediate buffer and a flushing thread.117//118// Interface:119//120// initialize() is called once when JVM is initialized. It creates and initializes the singleton instance of AsyncLogWriter.121// Once async logging is established, there's no way to turn it off.122//123// instance() is MT-safe and returns the pointer of the singleton instance if and only if async logging is enabled and has124// successfully initialized. Clients can use its return value to determine async logging is established or not.125//126// enqueue() is the basic operation of AsyncLogWriter. Two overloading versions of it are provided to match LogOutput::write().127// They are both MT-safe and non-blocking. Derived classes of LogOutput can invoke the corresponding enqueue() in write() and128// return 0. AsyncLogWriter is responsible of copying neccessary data.129//130// flush() ensures that all pending messages have been written out before it returns. It is not MT-safe in itself. When users131// change the logging configuration via jcmd, LogConfiguration::configure_output() calls flush() under the protection of the132// ConfigurationLock. In addition flush() is called during JVM termination, via LogConfiguration::finalize.133class AsyncLogWriter : public NonJavaThread {134class AsyncLogLocker;135136static AsyncLogWriter* _instance;137Semaphore _flush_sem;138// Can't use a Monitor here as we need a low-level API that can be used without Thread::current().139os::PlatformMonitor _lock;140bool _data_available;141volatile bool _initialized;142AsyncLogMap _stats; // statistics for dropped messages143AsyncLogBuffer _buffer;144145// The memory use of each AsyncLogMessage (payload) consists of itself and a variable-length c-str message.146// A regular logging message is smaller than vwrite_buffer_size, which is defined in logtagset.cpp147const size_t _buffer_max_size = {AsyncLogBufferSize / (sizeof(AsyncLogMessage) + vwrite_buffer_size)};148149AsyncLogWriter();150void enqueue_locked(const AsyncLogMessage& msg);151void write();152void run() override;153void pre_run() override {154NonJavaThread::pre_run();155log_debug(logging, thread)("starting AsyncLog Thread tid = " INTX_FORMAT, os::current_thread_id());156}157char* name() const override { return (char*)"AsyncLog Thread"; }158bool is_Named_thread() const override { return true; }159void print_on(outputStream* st) const override {160st->print("\"%s\" ", name());161Thread::print_on(st);162st->cr();163}164165public:166void enqueue(LogFileOutput& output, const LogDecorations& decorations, const char* msg);167void enqueue(LogFileOutput& output, LogMessageBuffer::Iterator msg_iterator);168169static AsyncLogWriter* instance();170static void initialize();171static void flush();172};173174#endif // SHARE_LOGGING_LOGASYNCWRITER_HPP175176177