1 /*
2  * Copyright (c) 2020, 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_JFREPOCHQUEUE_HPP
26 #define SHARE_JFR_UTILITIES_JFREPOCHQUEUE_HPP
27 
28 #include "jfr/recorder/storage/jfrEpochStorage.hpp"
29 
30 /*
31  * An ElmentPolicy template template argument provides the implementation for how elements
32  * associated with the queue is encoded and managed by exposing the following members:
33  *
34  *  ElmentPolicy::Type                             the type of the element to be stored in the queue.
35  *  size_t element_size(Type* t);                  per element storage size requirement.
36  *  void store_element(Type* t, Buffer* buffer);   encode and store element of Type into storage of type Buffer.
37  *  Buffer* thread_local_storage(Thread* thread);  quick access to thread local storage.
38  *  void set_thread_lcoal_storage(Buffer* buffer, Thread* thread); store back capability for newly acquired storage.
39  *
40  * The ElementPolicy is also the callback when iterating elements of the queue.
41  * The iteration callback signature to be provided by the policy class:
42  *
43  *  size_t operator()(const u1* next_element, Callback& callback, bool previous_epoch = false);
44  */
45 template <template <typename> class ElementPolicy>
46 class JfrEpochQueue : public JfrCHeapObj {
47  public:
48   typedef JfrEpochStorage::Buffer Buffer;
49   typedef JfrEpochStorage::BufferPtr BufferPtr;
50   typedef typename ElementPolicy<Buffer>::Type Type;
51   typedef const Type* TypePtr;
52   JfrEpochQueue();
53   ~JfrEpochQueue();
54   bool initialize(size_t min_buffer_size, size_t free_list_cache_count_limit, size_t cache_prealloc_count);
55   void enqueue(TypePtr t);
56   template <typename Callback>
57   void iterate(Callback& callback, bool previous_epoch = false);
58  private:
59   typedef ElementPolicy<Buffer> Policy;
60   Policy _policy;
61   JfrEpochStorage* _storage;
62   BufferPtr storage_for_element(TypePtr t, size_t element_size);
63 
64   template <typename Callback>
65   class ElementDispatch {
66    private:
67     Callback& _callback;
68     Policy& _policy;
69    public:
70     typedef Buffer Type;
71     ElementDispatch(Callback& callback, Policy& policy);
72     size_t operator()(const u1* element, bool previous_epoch);
73   };
74 };
75 
76 #endif // SHARE_JFR_UTILITIES_JFREPOCHQUEUE_HPP
77