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_RECORDER_STORAGE_JFREPOCHSTORAGE_INLINE_HPP
 26 #define SHARE_JFR_RECORDER_STORAGE_JFREPOCHSTORAGE_INLINE_HPP
 27 
 28 #include "jfr/recorder/storage/jfrEpochStorage.hpp"
 29 
 30 #include "jfr/recorder/storage/jfrMemorySpace.inline.hpp"
 31 #include "jfr/recorder/storage/jfrStorageUtils.inline.hpp"
 32 #include "jfr/utilities/jfrConcurrentQueue.inline.hpp"
 33 #include "jfr/utilities/jfrLinkedList.inline.hpp"
 34 #include "logging/log.hpp"
 35 
 36 template <typename NodeType, template <typename> class RetrievalPolicy, bool EagerReclaim>
 37 JfrEpochStorageHost<NodeType, RetrievalPolicy, EagerReclaim>::JfrEpochStorageHost() : _mspace(NULL) {}
 38 
 39 template <typename NodeType, template <typename> class RetrievalPolicy, bool EagerReclaim>
 40 JfrEpochStorageHost<NodeType, RetrievalPolicy, EagerReclaim>::~JfrEpochStorageHost() {
 41   delete _mspace;
 42 }
 43 
 44 template <typename NodeType, template <typename> class RetrievalPolicy, bool EagerReclaim>
 45 bool JfrEpochStorageHost<NodeType, RetrievalPolicy, EagerReclaim>::initialize(size_t min_elem_size, size_t free_list_cache_count_limit, size_t cache_prealloc_count) {
 46   assert(_mspace == NULL, "invariant");
 47   _mspace = new EpochMspace(min_elem_size, free_list_cache_count_limit, this);
 48   return _mspace != NULL && _mspace->initialize(cache_prealloc_count);
 49 }
 50 
 51 template <typename NodeType, template <typename> class RetrievalPolicy, bool EagerReclaim>
 52 inline NodeType* JfrEpochStorageHost<NodeType, RetrievalPolicy, EagerReclaim>::acquire(size_t size, Thread* thread) {
 53   BufferPtr buffer = mspace_acquire_to_live_list(size, _mspace, thread);
 54   if (buffer == NULL) {
 55     log_warning(jfr)("Unable to allocate " SIZE_FORMAT " bytes of %s.", _mspace->min_element_size(), "epoch storage");
 56     return NULL;
 57   }
 58   assert(buffer->acquired_by_self(), "invariant");
 59   return buffer;
 60 }
 61 
 62 template <typename NodeType, template <typename> class RetrievalPolicy, bool EagerReclaim>
 63 void JfrEpochStorageHost<NodeType, RetrievalPolicy, EagerReclaim>::release(NodeType* buffer) {
 64   assert(buffer != NULL, "invariant");
 65   buffer->set_retired();
 66 }
 67 
 68 template <typename NodeType, template <typename> class RetrievalPolicy, bool EagerReclaim>
 69 void JfrEpochStorageHost<NodeType, RetrievalPolicy, EagerReclaim>::register_full(NodeType* buffer, Thread* thread) {
 70   // nothing here at the moment
 71 }
 72 
 73 template <typename NodeType, template <typename> class RetrievalPolicy, bool EagerReclaim>
 74 template <typename Functor>
 75 void JfrEpochStorageHost<NodeType, RetrievalPolicy, EagerReclaim>::iterate(Functor& functor, bool previous_epoch) {
 76   typedef ReinitializeAllReleaseRetiredOp<EpochMspace, typename EpochMspace::LiveList> PreviousEpochReleaseOperation;
 77   typedef CompositeOperation<Functor, PreviousEpochReleaseOperation> PreviousEpochOperation;
 78   typedef ReleaseRetiredOp<EpochMspace, typename EpochMspace::LiveList> CurrentEpochReleaseOperation;
 79   typedef CompositeOperation<Functor, CurrentEpochReleaseOperation> CurrentEpochOperation;
 80   if (previous_epoch) {
 81     PreviousEpochReleaseOperation pero(_mspace, _mspace->live_list(true));
 82     PreviousEpochOperation peo(&functor, &pero);
 83     process_live_list(peo, _mspace, true); // previous epoch list
 84     return;
 85   }
 86   if (EagerReclaim) {
 87     CurrentEpochReleaseOperation cero(_mspace, _mspace->live_list());
 88     CurrentEpochOperation ceo(&functor, &cero);
 89     process_live_list(ceo, _mspace, false); // current epoch list
 90     return;
 91   }
 92   process_live_list(functor, _mspace, false); // current epoch list
 93 }
 94 
 95 #ifdef ASSERT
 96 
 97 template <typename Mspace>
 98 class EmptyVerifier {
 99  private:
100   Mspace* _mspace;
101  public:
102   typedef typename Mspace::Node Node;
103   typedef typename Mspace::NodePtr NodePtr;
104   EmptyVerifier(Mspace* mspace) : _mspace(mspace) {}
105   bool process(NodePtr node) {
106     assert(node != NULL, "invariant");
107     assert(node->empty(), "invariant");
108     return true;
109   }
110 };
111 
112 template <typename NodeType, template <typename> class RetrievalPolicy, bool EagerReclaim>
113 void JfrEpochStorageHost<NodeType, RetrievalPolicy, EagerReclaim>::verify_previous_empty() const {
114   typedef EmptyVerifier<JfrEpochStorage::Mspace> VerifyEmptyMspace;
115   VerifyEmptyMspace vem(_mspace);
116   process_live_list(vem, _mspace, true);
117 }
118 
119 #endif // ASSERT
120 
121 #endif // SHARE_JFR_RECORDER_STORAGE_JFREPOCHSTORAGE_INLINE_HPP
--- EOF ---