Commit 028a03b5 by Danila Klimenko

Performance optimizations (UniqueHazardPointer local copy; Tree node leaf/sentinel flags)

parent 11e59de4
......@@ -422,12 +422,16 @@ const double embb::containers::internal::HazardPointer<GuardType>::
template<typename Type>
UniqueHazardPointer<Type>::
UniqueHazardPointer()
: hazard_guard_(NULL), undefined_guard_(NULL), active_(false) {}
: hazard_guard_(NULL),
local_ptr_value_(NULL),
undefined_guard_(NULL),
active_(false) {}
template<typename Type>
UniqueHazardPointer<Type>::
UniqueHazardPointer(AtomicTypePtr& hazard_guard, Type* undefined_guard)
: hazard_guard_(&hazard_guard),
local_ptr_value_(hazard_guard_->Load()),
undefined_guard_(undefined_guard),
active_(LoadGuardedPointer() == undefined_guard_) {}
......@@ -487,6 +491,7 @@ void UniqueHazardPointer<Type>::AdoptHazard(const UniqueHazardPointer& other) {
template<typename Type>
void UniqueHazardPointer<Type>::Swap(UniqueHazardPointer& other) {
std::swap(hazard_guard_, other.hazard_guard_);
std::swap(local_ptr_value_, other.local_ptr_value_);
std::swap(undefined_guard_, other.undefined_guard_);
std::swap(active_, other.active_);
}
......@@ -517,12 +522,13 @@ void UniqueHazardPointer<Type>::ClearHazard() {
template<typename Type>
Type* UniqueHazardPointer<Type>::LoadGuardedPointer() const {
return hazard_guard_->Load();
return local_ptr_value_;
}
template<typename Type>
void UniqueHazardPointer<Type>::StoreGuardedPointer(Type* ptr) {
hazard_guard_->Store(ptr);
local_ptr_value_ = ptr;
}
template<typename Type>
......
......@@ -692,6 +692,8 @@ class UniqueHazardPointer {
* hazardous pointers
*/
AtomicTypePtr* hazard_guard_;
/** Local copy of the guarded pointer value (used for optimization) */
Type* local_ptr_value_;
/** Dummy value used to clear the hazard guard from any hazards */
Type* undefined_guard_;
/** Flag set to true when the guard is protecting some hazardous pointer */
......
......@@ -33,6 +33,8 @@
#include <embb/base/c/errors.h>
#include <embb/base/mutex.h>
#include <embb/containers/internal/hazard_pointer.h>
#include <embb/containers/lock_free_tree_value_pool.h>
#include <embb/containers/object_pool.h>
namespace embb {
namespace containers {
......@@ -124,6 +126,20 @@ class ChromaticTreeNode {
Node* GetRight() const;
/**
* Checks if the node is a leaf.
*
* @return \c true if node is a leaf, \c false otherwise
*/
bool IsLeaf() const;
/**
* Checks if the node is a sentinel.
*
* @return \c true if node is a sentinel, \c false otherwise
*/
bool IsSentinel() const;
/**
* Tries to replace one of the child pointers that compares equal to
* \c old_child with the \c new_child using an atomic compare-and-swap
* operation. If neither left nor right child pointer is pointing to
......@@ -169,6 +185,8 @@ class ChromaticTreeNode {
const Key key_; /**< Stored key. */
const Value value_; /**< Stored value. */
const int weight_; /**< Weight of the node. */
const bool is_leaf_; /**< True if node is a leaf. */
const bool is_sentinel_; /**< True if node is a sentinel. */
AtomicNodePtr left_; /**< Pointer to left child node. */
AtomicNodePtr right_; /**< Pointer to right child node. */
AtomicFlag retired_; /**< Retired (marked for deletion) flag. */
......@@ -692,24 +710,6 @@ class ChromaticTree {
HazardNodePtr& grandparent);
/**
* Checks whether the given node is a leaf.
*
* \param[IN] node Node to be checked
*
* \return \c true if the given node is a leaf, \c false otherwise
*/
bool IsLeaf(const Node* node) const;
/**
* Checks whether the given node is a sentinel node.
*
* \param[IN] node Node to be checked
*
* \return \c true if the given node is a sentinel node, \c false otherwise
*/
bool IsSentinel(const Node* node) const;
/**
* Checks whether the given node has a specified child node.
*
* \param[IN] parent Parent node
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment