Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/jfr/utilities/jfrVersionSystem.inline.hpp
41149 views
1
/*
2
* Copyright (c) 2020, 2021, 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_UTILITIES_JFRVERSIONSYSTEM_INLINE_HPP
26
#define SHARE_JFR_UTILITIES_JFRVERSIONSYSTEM_INLINE_HPP
27
28
#include "jfr/utilities/jfrVersionSystem.hpp"
29
30
#include "runtime/atomic.hpp"
31
#include "runtime/os.hpp"
32
33
inline JfrVersionSystem::JfrVersionSystem() : _tip(), _head(NULL) {
34
_tip._value = 1;
35
}
36
37
inline JfrVersionSystem::~JfrVersionSystem() {
38
reset();
39
}
40
41
inline void JfrVersionSystem::reset() {
42
NodePtr node = _head;
43
while (node != NULL) {
44
NodePtr next = node->_next;
45
delete node;
46
node = next;
47
}
48
_head = NULL;
49
_tip._value = 1;
50
}
51
52
inline JfrVersionSystem::Type JfrVersionSystem::tip() const {
53
return Atomic::load(&_tip._value);
54
}
55
56
inline JfrVersionSystem::Type JfrVersionSystem::inc_tip() {
57
traceid cmp;
58
traceid xchg;
59
do {
60
cmp = _tip._value;
61
xchg = cmp + 1;
62
} while (Atomic::cmpxchg(&_tip._value, cmp, xchg) != cmp);
63
return xchg;
64
}
65
66
inline JfrVersionSystem::NodePtr JfrVersionSystem::acquire() {
67
NodePtr node = _head;
68
// free
69
while (node != NULL) {
70
if (node->_live || Atomic::cmpxchg(&node->_live, false, true)) {
71
node = node->_next;
72
continue;
73
}
74
DEBUG_ONLY(assert_state(node);)
75
return node;
76
}
77
// new
78
node = new Node(this);
79
NodePtr next;
80
do {
81
next = _head;
82
node->_next = next;
83
} while (Atomic::cmpxchg(&_head, next, node) != next);
84
DEBUG_ONLY(assert_state(node);)
85
return node;
86
}
87
88
inline JfrVersionSystem::Handle JfrVersionSystem::get() {
89
return Handle::make(acquire());
90
}
91
92
inline JfrVersionSystem::Node::Node(JfrVersionSystem* system) : _system(system), _next(NULL), _version(0), _live(true) {}
93
94
inline traceid JfrVersionSystem::Node::version() const {
95
return _version;
96
}
97
98
inline void JfrVersionSystem::Node::set(traceid version) const {
99
Atomic::release_store_fence(&_version, version);
100
}
101
102
inline void JfrVersionSystem::Node::add_ref() const {
103
_ref_counter.inc();
104
}
105
106
inline void JfrVersionSystem::Node::remove_ref() const {
107
if (_ref_counter.dec()) {
108
assert(_live, "invariant");
109
set(0);
110
_live = false;
111
}
112
}
113
114
inline void JfrVersionSystem::Node::checkout() {
115
set(_system->tip());
116
assert(version() != 0, "invariant");
117
}
118
119
inline void JfrVersionSystem::Node::commit() {
120
assert(version() != 0, "invariant");
121
// A commit consist of an atomic increment of the tip.
122
const Type commit_version = _system->inc_tip();
123
// Release this checkout.
124
set(0);
125
// Await release of checkouts for earlier versions.
126
_system->await(commit_version);
127
}
128
129
inline JfrVersionSystem::NodePtr
130
JfrVersionSystem::synchronize_with(JfrVersionSystem::Type version, JfrVersionSystem::NodePtr node) const {
131
assert(version <= tip(), "invariant");
132
while (node != NULL) {
133
const Type checkedout = Atomic::load_acquire(&node->_version);
134
if (checkedout > 0 && checkedout < version) {
135
return node;
136
}
137
node = node->_next;
138
}
139
return NULL;
140
}
141
142
inline void JfrVersionSystem::await(JfrVersionSystem::Type version) {
143
assert(version > 0, "invariant");
144
static const int backoff_unit_ns = 10;
145
int backoff_factor = 1;
146
NodePtr last = _head;
147
while (true) {
148
last = synchronize_with(version, last);
149
if (last == NULL) {
150
return;
151
}
152
os::naked_short_nanosleep(backoff_unit_ns * backoff_factor++);
153
}
154
}
155
156
#ifdef ASSERT
157
inline void JfrVersionSystem::assert_state(const JfrVersionSystem::Node* node) const {
158
assert(node != NULL, "invariant");
159
assert(node->_live, "invariant");
160
assert(node->_version == 0, "invariant");
161
assert(node->_ref_counter.current() == 0, "invariant");
162
}
163
#endif // ASSERT
164
165
#endif // SHARE_JFR_UTILITIES_JFRVERSIONSYSTEM_INLINE_HPP
166
167