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 #ifndef SHARE_LOGGING_ASYNC_FLUSHER_HPP 25 #define SHARE_LOGGING_ASYNC_FLUSHER_HPP 26 27 #include "memory/resourceArea.hpp" 28 #include "runtime/mutexLocker.hpp" 29 #include "runtime/task.hpp" 30 #include "utilities/linkedlist.hpp" 31 #include "utilities/pair.hpp" 32 33 template <typename E> 34 class LinkedListFIFO : private LinkedListImpl<E, ResourceObj::C_HEAP, mtLogging> { 35 private: 36 LinkedListNode<E>* _tail; 37 38 // this is not a generic FIFO, template parameter is only for testing. 39 public: 40 LinkedListFIFO() : _tail(NULL) {} 41 void push(const E& e) { 42 if (!_tail) 43 _tail = this->add(e); 44 else 45 _tail = this->insert_after(e, _tail); 46 } 47 48 void pop_all(LinkedList<E>* logs) { 49 logs->move(static_cast<LinkedList<E>* >(this)); 50 _tail = NULL; 51 } 52 }; 53 54 class LogMessageBuffer; 55 class LogTagSet; 56 class AsyncLogMessage : private Pair<LogTagSet*, LogMessageBuffer*> { 57 AsyncLogMessage(LogTagSet* t, LogMessageBuffer* b) 58 : Pair<LogTagSet*, LogMessageBuffer*>(t, b) {} 59 60 public: 61 static AsyncLogMessage create(LogTagSet* t, LogMessageBuffer* b) { 62 return AsyncLogMessage(t, b); 63 } 64 65 bool equals(const AsyncLogMessage& o) const { 66 return first == o.first && second == o.second; 67 } 68 69 LogTagSet* tagset() { return first; } 70 LogMessageBuffer* buffer() { return second; } 71 }; 72 73 typedef LinkedListFIFO<AsyncLogMessage> AsyncLogFIFO; 74 75 class LogAsyncFlusher : public PeriodicTask { 76 friend class AsyncLogTest_flusher_test_vm_Test; 77 private: 78 static LogAsyncFlusher* _instance; 79 Mutex _lock; 80 AsyncLogFIFO _fifo; 81 82 LogAsyncFlusher(size_t interval/*ms*/) : PeriodicTask(interval), 83 _lock(Mutex::tty, "logAsyncFlusher", 84 Mutex::_allow_vm_block_flag, Mutex::_safepoint_check_never) { 85 this->enroll(); 86 } 87 88 ~LogAsyncFlusher(); 89 90 public: 91 void enqueue(LogTagSet* tagset, LogMessageBuffer* buf); 92 93 virtual void task(); 94 void flush() { task(); } 95 96 // none of following functions are thread-safe. 97 // Meyer's singleton is not thread-safe until C++11. 98 static void initialize(); 99 static void cleanup(); 100 static LogAsyncFlusher* instance(); 101 }; 102 103 #endif // SHARE_LOGGING_ASYNC_FLUSHER_HPP