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_RECORDER_STORAGE_JFRSTORAGEUTILS_HPP
26 #define SHARE_JFR_RECORDER_STORAGE_JFRSTORAGEUTILS_HPP
27 
28 #include "jfr/recorder/storage/jfrBuffer.hpp"
29 #include "jfr/recorder/repository/jfrChunkWriter.hpp"
30 #include "jfr/utilities/jfrAllocation.hpp"
31 #include "jfr/utilities/jfrTypes.hpp"
32 #include "runtime/thread.hpp"
33 
34 class CompositeOperationOr {
35  public:
evaluate(bool value)36   static bool evaluate(bool value) {
37     return !value;
38   }
39 };
40 
41 class CompositeOperationAnd {
42  public:
evaluate(bool value)43   static bool evaluate(bool value) {
44     return value;
45   }
46 };
47 
48 template <typename Operation, typename NextOperation, typename TruthFunction = CompositeOperationAnd>
49 class CompositeOperation {
50  private:
51   Operation* _op;
52   NextOperation* _next;
53  public:
CompositeOperation(Operation * op,NextOperation * next)54   CompositeOperation(Operation* op, NextOperation* next) : _op(op), _next(next) {
55     assert(_op != NULL, "invariant");
56   }
57   typedef typename Operation::Type Type;
process(Type * t)58   bool process(Type* t) {
59     const bool op_result = _op->process(t);
60     return _next == NULL ? op_result : TruthFunction::evaluate(op_result) ? _next->process(t) : op_result;
61   }
elements() const62   size_t elements() const {
63     return _next == NULL ? _op->elements() : _op->elements() + _next->elements();
64   }
size() const65   size_t size() const {
66     return _next == NULL ? _op->size() : _op->size() + _next->size();
67   }
68 };
69 
70 template <typename T>
71 class UnBufferedWriteToChunk {
72  private:
73   JfrChunkWriter& _writer;
74   size_t _elements;
75   size_t _size;
76  public:
77   typedef T Type;
UnBufferedWriteToChunk(JfrChunkWriter & writer)78   UnBufferedWriteToChunk(JfrChunkWriter& writer) : _writer(writer), _elements(0), _size(0) {}
79   bool write(Type* t, const u1* data, size_t size);
elements() const80   size_t elements() const { return _elements; }
size() const81   size_t size() const { return _size; }
82 };
83 
84 template <typename T>
85 class DefaultDiscarder {
86  private:
87   size_t _elements;
88   size_t _size;
89  public:
90   typedef T Type;
DefaultDiscarder()91   DefaultDiscarder() : _elements(0), _size(0) {}
92   bool discard(Type* t, const u1* data, size_t size);
elements() const93   size_t elements() const { return _elements; }
size() const94   size_t size() const { return _size; }
95 };
96 
97 template <typename T, bool negation>
98 class Retired {
99  public:
100   typedef T Type;
process(Type * t)101   bool process(Type* t) {
102     assert(t != NULL, "invariant");
103     return negation ? !t->retired() : t->retired();
104   }
105 };
106 
107 template <typename T, bool negation>
108 class Excluded {
109  public:
110   typedef T Type;
process(Type * t)111   bool process(Type* t) {
112     assert(t != NULL, "invariant");
113     return negation ? !t->excluded() : t->excluded();
114   }
115 };
116 
117 template <typename Operation>
118 class MutexedWriteOp {
119  private:
120   Operation& _operation;
121  public:
122   typedef typename Operation::Type Type;
MutexedWriteOp(Operation & operation)123   MutexedWriteOp(Operation& operation) : _operation(operation) {}
124   bool process(Type* t);
elements() const125   size_t elements() const { return _operation.elements(); }
size() const126   size_t size() const { return _operation.size(); }
127 };
128 
129 template <typename Operation, typename Predicate>
130 class PredicatedMutexedWriteOp : public MutexedWriteOp<Operation> {
131  private:
132   Predicate& _predicate;
133  public:
PredicatedMutexedWriteOp(Operation & operation,Predicate & predicate)134   PredicatedMutexedWriteOp(Operation& operation, Predicate& predicate) :
135     MutexedWriteOp<Operation>(operation), _predicate(predicate) {}
process(typename Operation::Type * t)136   bool process(typename Operation::Type* t) {
137     return _predicate.process(t) ? MutexedWriteOp<Operation>::process(t) : true;
138   }
139 };
140 
141 template <typename Operation>
142 class ConcurrentWriteOp {
143  private:
144   Operation& _operation;
145  public:
146   typedef typename Operation::Type Type;
ConcurrentWriteOp(Operation & operation)147   ConcurrentWriteOp(Operation& operation) : _operation(operation) {}
148   bool process(Type* t);
elements() const149   size_t elements() const { return _operation.elements(); }
size() const150   size_t size() const { return _operation.size(); }
151 };
152 
153 template <typename Operation, typename Predicate>
154 class PredicatedConcurrentWriteOp : public ConcurrentWriteOp<Operation> {
155  private:
156   Predicate& _predicate;
157  public:
PredicatedConcurrentWriteOp(Operation & operation,Predicate & predicate)158   PredicatedConcurrentWriteOp(Operation& operation, Predicate& predicate) :
159     ConcurrentWriteOp<Operation>(operation), _predicate(predicate) {}
process(typename Operation::Type * t)160   bool process(typename Operation::Type* t) {
161     return _predicate.process(t) ? ConcurrentWriteOp<Operation>::process(t) : true;
162   }
163 };
164 
165 template <typename Operation>
166 class ExclusiveOp : private MutexedWriteOp<Operation> {
167  public:
168   typedef typename Operation::Type Type;
ExclusiveOp(Operation & operation)169   ExclusiveOp(Operation& operation) : MutexedWriteOp<Operation>(operation) {}
170   bool process(Type* t);
processed() const171   size_t processed() const { return MutexedWriteOp<Operation>::processed(); }
172 };
173 
174 enum jfr_operation_mode {
175   mutexed = 1,
176   concurrent
177 };
178 
179 template <typename Operation>
180 class DiscardOp {
181  private:
182   Operation _operation;
183   jfr_operation_mode _mode;
184  public:
185   typedef typename Operation::Type Type;
DiscardOp(jfr_operation_mode mode=concurrent)186   DiscardOp(jfr_operation_mode mode = concurrent) : _operation(), _mode(mode) {}
187   bool process(Type* t);
elements() const188   size_t elements() const { return _operation.elements(); }
size() const189   size_t size() const { return _operation.size(); }
190 };
191 
192 #endif // SHARE_JFR_RECORDER_STORAGE_JFRSTORAGEUTILS_HPP
193