--- /dev/null 2020-02-13 04:30:26.348000000 +0000 +++ new/src/hotspot/share/logging/logAsyncFlusher.hpp 2020-02-24 07:47:48.541126895 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#ifndef SHARE_LOGGING_ASYNC_FLUSHER_HPP +#define SHARE_LOGGING_ASYNC_FLUSHER_HPP + +#include "memory/resourceArea.hpp" +#include "runtime/mutexLocker.hpp" +#include "runtime/task.hpp" +#include "utilities/linkedlist.hpp" +#include "utilities/pair.hpp" + +template +class LinkedListFIFO : private LinkedListImpl { + private: + LinkedListNode* _tail; + + // this is not a generic FIFO, template parameter is only for testing. + public: + LinkedListFIFO() : _tail(NULL) {} + void push(const E& e) { + if (!_tail) + _tail = this->add(e); + else + _tail = this->insert_after(e, _tail); + } + + void pop_all(LinkedList* logs) { + logs->move(static_cast* >(this)); + _tail = NULL; + } +}; + +class LogMessageBuffer; +class LogTagSet; +class AsyncLogMessage : private Pair { + AsyncLogMessage(LogTagSet* t, LogMessageBuffer* b) + : Pair(t, b) {} + +public: + static AsyncLogMessage create(LogTagSet* t, LogMessageBuffer* b) { + return AsyncLogMessage(t, b); + } + + bool equals(const AsyncLogMessage& o) const { + return first == o.first && second == o.second; + } + + LogTagSet* tagset() { return first; } + LogMessageBuffer* buffer() { return second; } +}; + +typedef LinkedListFIFO AsyncLogFIFO; + +class LogAsyncFlusher : public PeriodicTask { + friend class AsyncLogTest_flusher_test_vm_Test; + private: + static LogAsyncFlusher* _instance; + Mutex _lock; + AsyncLogFIFO _fifo; + + LogAsyncFlusher(size_t interval/*ms*/) : PeriodicTask(interval), + _lock(Mutex::tty, "logAsyncFlusher", + Mutex::_allow_vm_block_flag, Mutex::_safepoint_check_never) { + this->enroll(); + } + + ~LogAsyncFlusher(); + + public: + void enqueue(LogTagSet* tagset, LogMessageBuffer* buf); + + virtual void task(); + void flush() { task(); } + + // none of following functions are thread-safe. + // Meyer's singleton is not thread-safe until C++11. + static void initialize(); + static void cleanup(); + static LogAsyncFlusher* instance(); +}; + +#endif // SHARE_LOGGING_ASYNC_FLUSHER_HPP