Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/jfr/utilities/jfrVersionSystem.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_HPP
26
#define SHARE_JFR_UTILITIES_JFRVERSIONSYSTEM_HPP
27
28
/*
29
* A lock-free data structure usually require support for tracking references
30
* in the service of Safe Memory Reclamation (SMR). JfrVersionSystem provides local,
31
* compared to global, reference tracking for an assoicated data structure.
32
*
33
* A client, before accessing a structure, will perform a "checkout" from the JfrVersionSystem.
34
* This checkout is associated with the current, or latest, version, analogous to the "tip" in a version control system.
35
* When a client is done it releases its checkout, by which the JfrVersionSystem is notified that the client
36
* is no longer an active user of the associated structure.
37
*
38
* If a client performs a modification, it will register this with the JfrVersionSystem, by means of incrementing the current version.
39
*
40
* To guarantee safe memory reclamation, say before attempting a delete, a client will use the JfrVersionSystem to
41
* check for potential active uses, i.e. checkouts, with versions earlier than the version associated with a specific modification.
42
*
43
* Let's exemplify this with the removal of a node from a linked-list:
44
*
45
* 1. Before accessing the list, the client will check out the latest version from the JfrVersionSystem. This access is now tracked.
46
* 2. The client finds a node it wants to use, and excises the node from the list.
47
* 3. This excision is a modification so the client will increment the current version.
48
* 4. Before it can start to use proper the node just excised, the client must ensure no possible references exist.
49
* 5. To do this, the client inspects the JfrVersionSystem to possibly await the release of existing checkouts,
50
* i.e. for versions less than the version associated with the modification.
51
* 6. On return, the client is guaranteed exclusive access to the excised node.
52
*
53
* Tracking the version of a structure is conceptually similar to tracking a representative pointer using Hazard Pointers,
54
* or by using a global counter or some kind of ticket system.
55
*
56
* The implementation was inspired by Andrei Alexandrescu and Maged Michael, Lock-Free Data Structures with Hazard Pointers
57
* https ://www.drdobbs.com/lock-free-data-structures-with-hazard-po/184401890
58
*/
59
60
#include "jfr/utilities/jfrAllocation.hpp"
61
#include "jfr/utilities/jfrRefCountPointer.hpp"
62
#include "jfr/utilities/jfrTypes.hpp"
63
#include "memory/padded.hpp"
64
65
class JfrVersionSystem : public JfrCHeapObj {
66
public:
67
typedef traceid Type;
68
private:
69
class Node : public JfrCHeapObj {
70
friend class JfrVersionSystem;
71
template <typename>
72
friend class RefCountHandle;
73
private:
74
JfrVersionSystem* const _system;
75
Node* _next;
76
mutable Type _version;
77
SingleThreadedRefCounter _ref_counter;
78
mutable bool _live;
79
Node(JfrVersionSystem* system);
80
void add_ref() const;
81
void remove_ref() const;
82
Type version() const;
83
void set(Type version) const;
84
public:
85
void checkout();
86
void commit();
87
const Node* operator->() const { return this; }
88
Node* operator->() { return this; }
89
};
90
typedef Node* NodePtr;
91
92
public:
93
JfrVersionSystem();
94
~JfrVersionSystem();
95
void reset();
96
97
typedef RefCountHandle<Node> Handle;
98
Handle get();
99
100
private:
101
NodePtr acquire();
102
void await(Type version);
103
Type tip() const;
104
Type inc_tip();
105
NodePtr synchronize_with(Type version, NodePtr last) const;
106
DEBUG_ONLY(void assert_state(const Node* node) const;)
107
struct PaddedTip {
108
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
109
volatile Type _value;
110
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile Type));
111
};
112
PaddedTip _tip;
113
NodePtr _head;
114
};
115
116
#endif // SHARE_JFR_UTILITIES_JFRVERSIONSYSTEM_HPP
117
118