1 /* 2 * Copyright (c) 2016, 2018, 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 #ifndef SHARE_VM_JFR_WRITERS_JFRSTREAMWRITERHOST_INLINE_HPP 26 #define SHARE_VM_JFR_WRITERS_JFRSTREAMWRITERHOST_INLINE_HPP 27 28 #include "jfr/writers/jfrStreamWriterHost.hpp" 29 #include "runtime/os.hpp" 30 31 template <typename Adapter, typename AP> 32 StreamWriterHost<Adapter, AP>::StreamWriterHost(typename Adapter::StorageType* storage, Thread* thread) : 33 MemoryWriterHost<Adapter, AP>(storage, thread), _stream_pos(0), _fd(invalid_fd) { 34 } 35 36 template <typename Adapter, typename AP> 37 StreamWriterHost<Adapter, AP>::StreamWriterHost(typename Adapter::StorageType* storage, size_t size) : 38 MemoryWriterHost<Adapter, AP>(storage, size), _stream_pos(0), _fd(invalid_fd) { 39 } 40 41 template <typename Adapter, typename AP> 42 StreamWriterHost<Adapter, AP>::StreamWriterHost(Thread* thread) : 43 MemoryWriterHost<Adapter, AP>(thread), _stream_pos(0), _fd(invalid_fd) { 44 } 45 46 template <typename Adapter, typename AP> 47 inline intptr_t StreamWriterHost<Adapter, AP>::current_stream_position() const { 48 return this->used_offset() + _stream_pos; 49 } 50 51 template <typename Adapter, typename AP> 52 inline bool StreamWriterHost<Adapter, AP>::accommodate(size_t used, size_t requested) { 53 if (used > 0) { 54 this->flush(used); 55 } 56 assert(this->used_size() == 0, "invariant"); 57 if (this->available_size() >= requested) { 58 return true; 59 } 60 return StorageHost<Adapter, AP>::accommodate(0, requested); 61 } 62 63 template <typename Adapter, typename AP> 64 inline void StreamWriterHost<Adapter, AP>::bytes(void* dest, const void* buf, size_t len) { 65 if (len > this->available_size()) { 66 this->write_unbuffered(buf, len); 67 return; 68 } 69 MemoryWriterHost<Adapter, AP>::bytes(dest, buf, len); 70 } 71 72 template <typename Adapter, typename AP> 73 inline void StreamWriterHost<Adapter, AP>::flush(size_t size) { 74 assert(size > 0, "invariant"); 75 assert(this->is_valid(), "invariant"); 76 _stream_pos += os::write(_fd, this->start_pos(), (int)size); 77 StorageHost<Adapter, AP>::reset(); 78 assert(0 == this->used_offset(), "invariant"); 79 } 80 81 template <typename Adapter, typename AP> 82 inline bool StreamWriterHost<Adapter, AP>::has_valid_fd() const { 83 return invalid_fd != _fd; 84 } 85 86 template <typename Adapter, typename AP> 87 inline intptr_t StreamWriterHost<Adapter, AP>::current_offset() const { 88 return current_stream_position(); 89 } 90 91 template <typename Adapter, typename AP> 92 void StreamWriterHost<Adapter, AP>::seek(intptr_t offset) { 93 this->flush(); 94 assert(0 == this->used_offset(), "can only seek from beginning"); 95 _stream_pos = os::seek_to_file_offset(_fd, offset); 96 } 97 98 template <typename Adapter, typename AP> 99 void StreamWriterHost<Adapter, AP>::flush() { 100 if (this->is_valid()) { 101 const size_t used = this->used_size(); 102 if (used > 0) { 103 this->flush(used); 104 } 105 } 106 } 107 108 template <typename Adapter, typename AP> 109 void StreamWriterHost<Adapter, AP>::write_unbuffered(const void* buf, size_t len) { 110 this->flush(); 111 assert(0 == this->used_offset(), "can only seek from beginning"); 112 while (len > 0) { 113 const int n = MIN2<int>((int)len, INT_MAX); 114 _stream_pos += os::write(_fd, buf, n); 115 len -= n; 116 } 117 } 118 119 template <typename Adapter, typename AP> 120 inline bool StreamWriterHost<Adapter, AP>::is_valid() const { 121 return has_valid_fd(); 122 } 123 124 template <typename Adapter, typename AP> 125 inline void StreamWriterHost<Adapter, AP>::close_fd() { 126 assert(this->has_valid_fd(), "closing invalid fd!"); 127 os::close(_fd); 128 _fd = invalid_fd; 129 } 130 131 template <typename Adapter, typename AP> 132 inline void StreamWriterHost<Adapter, AP>::reset(fio_fd fd) { 133 assert(!this->has_valid_fd(), "invariant"); 134 _fd = fd; 135 _stream_pos = 0; 136 this->hard_reset(); 137 } 138 139 #endif // SHARE_VM_JFR_WRITERS_JFRSTREAMWRITERHOST_INLINE_HPP