1/*
2 * Copyright (c) 2016, 2019, 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_JFR_WRITERS_JFRSTREAMWRITERHOST_INLINE_HPP
26#define SHARE_JFR_WRITERS_JFRSTREAMWRITERHOST_INLINE_HPP
27
28#include "jfr/writers/jfrStreamWriterHost.hpp"
29#include "runtime/os.hpp"
30
31template <typename Adapter, typename AP>
32StreamWriterHost<Adapter, AP>::StreamWriterHost(typename Adapter::StorageType* storage, Thread* thread) :
33 MemoryWriterHost<Adapter, AP>(storage, thread), _stream_pos(0), _fd(invalid_fd) {
34}
35
36template <typename Adapter, typename AP>
37StreamWriterHost<Adapter, AP>::StreamWriterHost(typename Adapter::StorageType* storage, size_t size) :
38 MemoryWriterHost<Adapter, AP>(storage, size), _stream_pos(0), _fd(invalid_fd) {
39}
40
41template <typename Adapter, typename AP>
42StreamWriterHost<Adapter, AP>::StreamWriterHost(Thread* thread) :
43 MemoryWriterHost<Adapter, AP>(thread), _stream_pos(0), _fd(invalid_fd) {
44}
45
46template <typename Adapter, typename AP>
47inline int64_t StreamWriterHost<Adapter, AP>::current_stream_position() const {
48 return this->used_offset() + _stream_pos;
49}
50
51template <typename Adapter, typename AP>
52inline 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
63template <typename Adapter, typename AP>
64inline 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
72template <typename Adapter, typename AP>
73inline 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(), (unsigned int)size);
77 StorageHost<Adapter, AP>::reset();
78 assert(0 == this->used_offset(), "invariant");
79}
80
81template <typename Adapter, typename AP>
82inline bool StreamWriterHost<Adapter, AP>::has_valid_fd() const {
83 return invalid_fd != _fd;
84}
85
86template <typename Adapter, typename AP>
87inline int64_t StreamWriterHost<Adapter, AP>::current_offset() const {
88 return current_stream_position();
89}
90
91template <typename Adapter, typename AP>
92void StreamWriterHost<Adapter, AP>::seek(int64_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
98template <typename Adapter, typename AP>
99void 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
108template <typename Adapter, typename AP>
109void 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 unsigned int n = MIN2((unsigned int)len, (unsigned int)INT_MAX);
114 _stream_pos += os::write(_fd, buf, n);
115 len -= n;
116 }
117}
118
119template <typename Adapter, typename AP>
120inline bool StreamWriterHost<Adapter, AP>::is_valid() const {
121 return has_valid_fd();
122}
123
124template <typename Adapter, typename AP>
125inline 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
131template <typename Adapter, typename AP>
132inline 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_JFR_WRITERS_JFRSTREAMWRITERHOST_INLINE_HPP
140