/*
* Copyright ( c ) 2020 , 2022 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*
*/
#ifndef SHARE_JFR_UTILITIES_JFRVERSIONSYSTEM_HPP
#define SHARE_JFR_UTILITIES_JFRVERSIONSYSTEM_HPP
/*
* A lock - free data structure usually require support for tracking references
* in the service of Safe Memory Reclamation ( SMR ) . JfrVersionSystem provides local ,
* compared to global , reference tracking for an associated data structure .
*
* A client , before accessing a structure , will perform a " checkout " from the JfrVersionSystem .
* This checkout is associated with the current , or latest , version , analogous to the " tip " in a version control system .
* When a client is done it releases its checkout , by which the JfrVersionSystem is notified that the client
* is no longer an active user of the associated structure .
*
* If a client performs a modification , it will register this with the JfrVersionSystem , by means of incrementing the current version .
*
* To guarantee safe memory reclamation , say before attempting a delete , a client will use the JfrVersionSystem to
* check for potential active uses , i . e . checkouts , with versions earlier than the version associated with a specific modification .
*
* Let ' s exemplify this with the removal of a node from a linked - list :
*
* 1 . Before accessing the list , the client will check out the latest version from the JfrVersionSystem . This access is now tracked .
* 2 . The client finds a node it wants to use , and excises the node from the list .
* 3 . This excision is a modification so the client will increment the current version .
* 4 . Before it can start to use proper the node just excised , the client must ensure no possible references exist .
* 5 . To do this , the client inspects the JfrVersionSystem to possibly await the release of existing checkouts ,
* i . e . for versions less than the version associated with the modification .
* 6 . On return , the client is guaranteed exclusive access to the excised node .
*
* Tracking the version of a structure is conceptually similar to tracking a representative pointer using Hazard Pointers ,
* or by using a global counter or some kind of ticket system .
*
* The implementation was inspired by Andrei Alexandrescu and Maged Michael , Lock - Free Data Structures with Hazard Pointers
* https : //www.drdobbs.com/lock-free-data-structures-with-hazard-po/184401890
*/
#include "jfr/utilities/jfrAllocation.hpp"
#include "jfr/utilities/jfrRefCountPointer.hpp"
#include "jfr/utilities/jfrTypes.hpp"
#include "memory/padded.hpp"
class JfrVersionSystem : public JfrCHeapObj {
public :
typedef traceid Type;
private :
class Node : public JfrCHeapObj {
friend class JfrVersionSystem;
template <typename >
friend class RefCountHandle;
private :
JfrVersionSystem* const _system;
Node* _next;
mutable Type _version;
SingleThreadedRefCounter _ref_counter;
mutable bool _live;
Node(JfrVersionSystem* system);
void add_ref() const ;
void remove_ref() const ;
Type version() const ;
void set(Type version) const ;
public :
void checkout();
void commit();
const Node* operator ->() const { return this ; }
Node* operator ->() { return this ; }
};
typedef Node* NodePtr;
public :
JfrVersionSystem();
~JfrVersionSystem();
void reset();
typedef RefCountHandle<Node> Handle;
Handle get();
private :
NodePtr acquire();
void await(Type version);
Type tip() const ;
Type inc_tip();
NodePtr synchronize_with(Type version, NodePtr last) const ;
DEBUG_ONLY(void assert_state(const Node* node) const ;)
struct PaddedTip {
DEFINE_PAD_MINUS_SIZE(0 , DEFAULT_CACHE_LINE_SIZE, 0 );
volatile Type _value;
DEFINE_PAD_MINUS_SIZE(1 , DEFAULT_CACHE_LINE_SIZE, sizeof (volatile Type));
};
PaddedTip _tip;
NodePtr _head;
};
#endif // SHARE_JFR_UTILITIES_JFRVERSIONSYSTEM_HPP
Messung V0.5 in Prozent C=97 H=100 G=98
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-09-05)
¤
*© Formatika GbR, Deutschland