Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/logging/logOutputList.hpp
40930 views
1
/*
2
* Copyright (c) 2015, 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
#ifndef SHARE_LOGGING_LOGOUTPUTLIST_HPP
25
#define SHARE_LOGGING_LOGOUTPUTLIST_HPP
26
27
#include "logging/logLevel.hpp"
28
#include "memory/allocation.hpp"
29
#include "utilities/globalDefinitions.hpp"
30
31
class LogOutput;
32
33
// Data structure to keep track of log outputs for a given tagset.
34
// Essentially a sorted linked list going from error level outputs
35
// to outputs of finer levels. Keeps an index from each level to
36
// the first node in the list for the corresponding level.
37
// This allows a log message on, for example, info level to jump
38
// straight into the list where the first info level output can
39
// be found. The log message will then be printed on that output,
40
// as well as all outputs in nodes that follow in the list (which
41
// can be additional info level outputs and/or debug and trace outputs).
42
//
43
// Each instance keeps track of the number of current readers of the list.
44
// To remove a node from the list the node must first be unlinked,
45
// and the memory for that node can be freed whenever the removing
46
// thread observes an active reader count of 0 (after unlinking it).
47
class LogOutputList {
48
private:
49
struct LogOutputNode : public CHeapObj<mtLogging> {
50
LogOutput* _value;
51
LogOutputNode* _next;
52
LogLevelType _level;
53
};
54
55
LogOutputNode* _level_start[LogLevel::Count];
56
volatile jint _active_readers;
57
58
LogOutputNode* find(const LogOutput* output) const;
59
void remove_output(LogOutputNode* node);
60
void add_output(LogOutput* output, LogLevelType level);
61
void update_output_level(LogOutputNode* node, LogLevelType level);
62
63
// Bookkeeping functions to keep track of number of active readers/iterators for the list.
64
jint increase_readers();
65
jint decrease_readers();
66
67
public:
68
LogOutputList() : _active_readers(0) {
69
for (size_t i = 0; i < LogLevel::Count; i++) {
70
_level_start[i] = NULL;
71
}
72
}
73
74
// Test if the outputlist has an output for the given level.
75
bool is_level(LogLevelType level) const {
76
return _level_start[level] != NULL;
77
}
78
79
LogLevelType level_for(const LogOutput* output) const {
80
LogOutputNode* node = this->find(output);
81
if (node == NULL) {
82
return LogLevel::Off;
83
}
84
return node->_level;
85
}
86
87
// Set (add/update/remove) the output to the specified level.
88
void set_output_level(LogOutput* output, LogLevelType level);
89
90
// Removes all outputs. Equivalent of set_output_level(out, Off)
91
// for all outputs.
92
void clear();
93
void wait_until_no_readers() const;
94
95
class Iterator {
96
friend class LogOutputList;
97
private:
98
LogOutputNode* _current;
99
LogOutputList* _list;
100
Iterator(LogOutputList* list, LogOutputNode* start) : _current(start), _list(list) {
101
}
102
103
public:
104
Iterator(const Iterator &itr) : _current(itr._current), _list(itr._list){
105
itr._list->increase_readers();
106
}
107
108
Iterator& operator=(const Iterator& rhs) {
109
_current = rhs._current;
110
if (_list != rhs._list) {
111
rhs._list->increase_readers();
112
_list->decrease_readers();
113
_list = rhs._list;
114
}
115
return *this;
116
}
117
118
~Iterator() {
119
_list->decrease_readers();
120
}
121
122
LogOutput* operator*() {
123
return _current->_value;
124
}
125
126
void operator++(int) {
127
_current = _current->_next;
128
}
129
130
bool operator!=(const LogOutputNode *ref) const {
131
return _current != ref;
132
}
133
134
LogLevelType level() const {
135
return _current->_level;
136
}
137
};
138
139
Iterator iterator(LogLevelType level = LogLevel::Last) {
140
increase_readers();
141
return Iterator(this, _level_start[level]);
142
}
143
144
LogOutputNode* end() const {
145
return NULL;
146
}
147
};
148
149
#endif // SHARE_LOGGING_LOGOUTPUTLIST_HPP
150
151