Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
FORMUS3IC_LAS3
/
embb
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
028a03b5
authored
9 years ago
by
Danila Klimenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Performance optimizations (UniqueHazardPointer local copy; Tree node leaf/sentinel flags)
parent
11e59de4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
102 additions
and
70 deletions
+102
-70
containers_cpp/include/embb/containers/internal/hazard_pointer-inl.h
+8
-2
containers_cpp/include/embb/containers/internal/hazard_pointer.h
+2
-0
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-inl.h
+74
-50
containers_cpp/include/embb/containers/lock_free_chromatic_tree.h
+18
-18
No files found.
containers_cpp/include/embb/containers/internal/hazard_pointer-inl.h
View file @
028a03b5
...
@@ -422,12 +422,16 @@ const double embb::containers::internal::HazardPointer<GuardType>::
...
@@ -422,12 +422,16 @@ const double embb::containers::internal::HazardPointer<GuardType>::
template
<
typename
Type
>
template
<
typename
Type
>
UniqueHazardPointer
<
Type
>::
UniqueHazardPointer
<
Type
>::
UniqueHazardPointer
()
UniqueHazardPointer
()
:
hazard_guard_
(
NULL
),
undefined_guard_
(
NULL
),
active_
(
false
)
{}
:
hazard_guard_
(
NULL
),
local_ptr_value_
(
NULL
),
undefined_guard_
(
NULL
),
active_
(
false
)
{}
template
<
typename
Type
>
template
<
typename
Type
>
UniqueHazardPointer
<
Type
>::
UniqueHazardPointer
<
Type
>::
UniqueHazardPointer
(
AtomicTypePtr
&
hazard_guard
,
Type
*
undefined_guard
)
UniqueHazardPointer
(
AtomicTypePtr
&
hazard_guard
,
Type
*
undefined_guard
)
:
hazard_guard_
(
&
hazard_guard
),
:
hazard_guard_
(
&
hazard_guard
),
local_ptr_value_
(
hazard_guard_
->
Load
()),
undefined_guard_
(
undefined_guard
),
undefined_guard_
(
undefined_guard
),
active_
(
LoadGuardedPointer
()
==
undefined_guard_
)
{}
active_
(
LoadGuardedPointer
()
==
undefined_guard_
)
{}
...
@@ -487,6 +491,7 @@ void UniqueHazardPointer<Type>::AdoptHazard(const UniqueHazardPointer& other) {
...
@@ -487,6 +491,7 @@ void UniqueHazardPointer<Type>::AdoptHazard(const UniqueHazardPointer& other) {
template
<
typename
Type
>
template
<
typename
Type
>
void
UniqueHazardPointer
<
Type
>::
Swap
(
UniqueHazardPointer
&
other
)
{
void
UniqueHazardPointer
<
Type
>::
Swap
(
UniqueHazardPointer
&
other
)
{
std
::
swap
(
hazard_guard_
,
other
.
hazard_guard_
);
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
(
undefined_guard_
,
other
.
undefined_guard_
);
std
::
swap
(
active_
,
other
.
active_
);
std
::
swap
(
active_
,
other
.
active_
);
}
}
...
@@ -517,12 +522,13 @@ void UniqueHazardPointer<Type>::ClearHazard() {
...
@@ -517,12 +522,13 @@ void UniqueHazardPointer<Type>::ClearHazard() {
template
<
typename
Type
>
template
<
typename
Type
>
Type
*
UniqueHazardPointer
<
Type
>::
LoadGuardedPointer
()
const
{
Type
*
UniqueHazardPointer
<
Type
>::
LoadGuardedPointer
()
const
{
return
hazard_guard_
->
Load
()
;
return
local_ptr_value_
;
}
}
template
<
typename
Type
>
template
<
typename
Type
>
void
UniqueHazardPointer
<
Type
>::
StoreGuardedPointer
(
Type
*
ptr
)
{
void
UniqueHazardPointer
<
Type
>::
StoreGuardedPointer
(
Type
*
ptr
)
{
hazard_guard_
->
Store
(
ptr
);
hazard_guard_
->
Store
(
ptr
);
local_ptr_value_
=
ptr
;
}
}
template
<
typename
Type
>
template
<
typename
Type
>
...
...
This diff is collapsed.
Click to expand it.
containers_cpp/include/embb/containers/internal/hazard_pointer.h
View file @
028a03b5
...
@@ -692,6 +692,8 @@ class UniqueHazardPointer {
...
@@ -692,6 +692,8 @@ class UniqueHazardPointer {
* hazardous pointers
* hazardous pointers
*/
*/
AtomicTypePtr
*
hazard_guard_
;
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 */
/** Dummy value used to clear the hazard guard from any hazards */
Type
*
undefined_guard_
;
Type
*
undefined_guard_
;
/** Flag set to true when the guard is protecting some hazardous pointer */
/** Flag set to true when the guard is protecting some hazardous pointer */
...
...
This diff is collapsed.
Click to expand it.
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-inl.h
View file @
028a03b5
...
@@ -48,7 +48,9 @@ ChromaticTreeNode(const Key& key, const Value& value, int weight,
...
@@ -48,7 +48,9 @@ ChromaticTreeNode(const Key& key, const Value& value, int weight,
Node
*
left
,
Node
*
right
,
Operation
*
operation
)
Node
*
left
,
Node
*
right
,
Operation
*
operation
)
:
key_
(
key
),
:
key_
(
key
),
value_
(
value
),
value_
(
value
),
weight_
(
weight
),
weight_
(
weight
<
0
?
-
weight
:
weight
),
is_leaf_
(
left
==
NULL
),
is_sentinel_
(
weight
<
0
),
left_
(
left
),
left_
(
left
),
right_
(
right
),
right_
(
right
),
retired_
(
false
),
retired_
(
false
),
...
@@ -60,52 +62,64 @@ ChromaticTreeNode(const Key& key, const Value& value, int weight,
...
@@ -60,52 +62,64 @@ ChromaticTreeNode(const Key& key, const Value& value, int weight,
Operation
*
operation
)
Operation
*
operation
)
:
key_
(
key
),
:
key_
(
key
),
value_
(
value
),
value_
(
value
),
weight_
(
weight
),
weight_
(
weight
<
0
?
-
weight
:
weight
),
is_leaf_
(
true
),
is_sentinel_
(
weight
<
0
),
left_
(
NULL
),
left_
(
NULL
),
right_
(
NULL
),
right_
(
NULL
),
retired_
(
false
),
retired_
(
false
),
operation_
(
operation
)
{}
operation_
(
operation
)
{}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
const
Key
&
ChromaticTreeNode
<
Key
,
Value
>::
GetKey
()
const
{
inline
const
Key
&
ChromaticTreeNode
<
Key
,
Value
>::
GetKey
()
const
{
return
key_
;
return
key_
;
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
const
Value
&
ChromaticTreeNode
<
Key
,
Value
>::
GetValue
()
const
{
inline
const
Value
&
ChromaticTreeNode
<
Key
,
Value
>::
GetValue
()
const
{
return
value_
;
return
value_
;
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
int
ChromaticTreeNode
<
Key
,
Value
>::
GetWeight
()
const
{
in
line
in
t
ChromaticTreeNode
<
Key
,
Value
>::
GetWeight
()
const
{
return
weight_
;
return
weight_
;
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
typename
ChromaticTreeNode
<
Key
,
Value
>::
AtomicNodePtr
&
inline
typename
ChromaticTreeNode
<
Key
,
Value
>::
AtomicNodePtr
&
ChromaticTreeNode
<
Key
,
Value
>::
GetLeft
()
{
ChromaticTreeNode
<
Key
,
Value
>::
GetLeft
()
{
return
left_
;
return
left_
;
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
typename
ChromaticTreeNode
<
Key
,
Value
>::
Node
*
inline
typename
ChromaticTreeNode
<
Key
,
Value
>::
Node
*
ChromaticTreeNode
<
Key
,
Value
>::
GetLeft
()
const
{
ChromaticTreeNode
<
Key
,
Value
>::
GetLeft
()
const
{
return
left_
.
Load
();
return
left_
.
Load
();
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
typename
ChromaticTreeNode
<
Key
,
Value
>::
AtomicNodePtr
&
inline
typename
ChromaticTreeNode
<
Key
,
Value
>::
AtomicNodePtr
&
ChromaticTreeNode
<
Key
,
Value
>::
GetRight
()
{
ChromaticTreeNode
<
Key
,
Value
>::
GetRight
()
{
return
right_
;
return
right_
;
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
typename
ChromaticTreeNode
<
Key
,
Value
>::
Node
*
inline
typename
ChromaticTreeNode
<
Key
,
Value
>::
Node
*
ChromaticTreeNode
<
Key
,
Value
>::
GetRight
()
const
{
ChromaticTreeNode
<
Key
,
Value
>::
GetRight
()
const
{
return
right_
.
Load
();
return
right_
.
Load
();
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
inline
bool
ChromaticTreeNode
<
Key
,
Value
>::
IsLeaf
()
const
{
return
is_leaf_
;
}
template
<
typename
Key
,
typename
Value
>
inline
bool
ChromaticTreeNode
<
Key
,
Value
>::
IsSentinel
()
const
{
return
is_sentinel_
;
}
template
<
typename
Key
,
typename
Value
>
bool
ChromaticTreeNode
<
Key
,
Value
>::
bool
ChromaticTreeNode
<
Key
,
Value
>::
ReplaceChild
(
Node
*
old_child
,
Node
*
new_child
)
{
ReplaceChild
(
Node
*
old_child
,
Node
*
new_child
)
{
bool
replaced
=
false
;
bool
replaced
=
false
;
...
@@ -120,17 +134,17 @@ ReplaceChild(Node* old_child, Node* new_child) {
...
@@ -120,17 +134,17 @@ ReplaceChild(Node* old_child, Node* new_child) {
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
void
ChromaticTreeNode
<
Key
,
Value
>::
Retire
()
{
inline
void
ChromaticTreeNode
<
Key
,
Value
>::
Retire
()
{
retired_
=
true
;
retired_
=
true
;
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
bool
ChromaticTreeNode
<
Key
,
Value
>::
IsRetired
()
const
{
inline
bool
ChromaticTreeNode
<
Key
,
Value
>::
IsRetired
()
const
{
return
retired_
;
return
retired_
;
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
typename
ChromaticTreeNode
<
Key
,
Value
>::
AtomicOperationPtr
&
inline
typename
ChromaticTreeNode
<
Key
,
Value
>::
AtomicOperationPtr
&
ChromaticTreeNode
<
Key
,
Value
>::
GetOperation
()
{
ChromaticTreeNode
<
Key
,
Value
>::
GetOperation
()
{
return
operation_
;
return
operation_
;
}
}
...
@@ -143,13 +157,16 @@ ChromaticTreeOperation<Key, Value>::ChromaticTreeOperation()
...
@@ -143,13 +157,16 @@ ChromaticTreeOperation<Key, Value>::ChromaticTreeOperation()
root_
(
NULL
),
root_
(
NULL
),
root_operation_
(
NULL
),
root_operation_
(
NULL
),
num_old_nodes_
(
0
),
num_old_nodes_
(
0
),
old_nodes_
(),
old_operations_
(),
new_child_
(
NULL
)
new_child_
(
NULL
)
#ifdef EMBB_DEBUG
#ifdef EMBB_DEBUG
,
deleted_
(
false
)
,
deleted_
(
false
)
#endif
#endif
{}
{
for
(
size_t
i
=
0
;
i
<
MAX_NODES
;
++
i
)
{
old_nodes_
[
i
]
=
NULL
;
old_operations_
[
i
]
=
NULL
;
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
void
ChromaticTreeOperation
<
Key
,
Value
>::
void
ChromaticTreeOperation
<
Key
,
Value
>::
...
@@ -292,7 +309,7 @@ void ChromaticTreeOperation<Key, Value>::HelpAbort(Node* node) {
...
@@ -292,7 +309,7 @@ void ChromaticTreeOperation<Key, Value>::HelpAbort(Node* node) {
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
bool
ChromaticTreeOperation
<
Key
,
Value
>::
IsAborted
()
{
inline
bool
ChromaticTreeOperation
<
Key
,
Value
>::
IsAborted
()
{
#ifdef EMBB_DEBUG
#ifdef EMBB_DEBUG
assert
(
!
deleted_
);
assert
(
!
deleted_
);
#endif
#endif
...
@@ -300,7 +317,7 @@ bool ChromaticTreeOperation<Key, Value>::IsAborted() {
...
@@ -300,7 +317,7 @@ bool ChromaticTreeOperation<Key, Value>::IsAborted() {
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
bool
ChromaticTreeOperation
<
Key
,
Value
>::
IsInProgress
()
{
inline
bool
ChromaticTreeOperation
<
Key
,
Value
>::
IsInProgress
()
{
#ifdef EMBB_DEBUG
#ifdef EMBB_DEBUG
assert
(
!
deleted_
);
assert
(
!
deleted_
);
#endif
#endif
...
@@ -309,7 +326,7 @@ bool ChromaticTreeOperation<Key, Value>::IsInProgress() {
...
@@ -309,7 +326,7 @@ bool ChromaticTreeOperation<Key, Value>::IsInProgress() {
}
}
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
bool
ChromaticTreeOperation
<
Key
,
Value
>::
IsCommitted
()
{
inline
bool
ChromaticTreeOperation
<
Key
,
Value
>::
IsCommitted
()
{
#ifdef EMBB_DEBUG
#ifdef EMBB_DEBUG
assert
(
!
deleted_
);
assert
(
!
deleted_
);
#endif
#endif
...
@@ -341,7 +358,14 @@ void ChromaticTreeOperation<Key, Value>::SetDeleted() {
...
@@ -341,7 +358,14 @@ void ChromaticTreeOperation<Key, Value>::SetDeleted() {
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
typename
ChromaticTreeOperation
<
Key
,
Value
>::
Operation
*
typename
ChromaticTreeOperation
<
Key
,
Value
>::
Operation
*
ChromaticTreeOperation
<
Key
,
Value
>::
GetInitialDummmy
()
{
ChromaticTreeOperation
<
Key
,
Value
>::
GetInitialDummmy
()
{
#ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable:4640)
#endif
static
ChromaticTreeOperation
initial_dummy
;
static
ChromaticTreeOperation
initial_dummy
;
#ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(pop)
#endif
initial_dummy
.
state_
=
STATE_COMMITTED
;
initial_dummy
.
state_
=
STATE_COMMITTED
;
...
@@ -351,7 +375,14 @@ ChromaticTreeOperation<Key, Value>::GetInitialDummmy() {
...
@@ -351,7 +375,14 @@ ChromaticTreeOperation<Key, Value>::GetInitialDummmy() {
template
<
typename
Key
,
typename
Value
>
template
<
typename
Key
,
typename
Value
>
typename
ChromaticTreeOperation
<
Key
,
Value
>::
Operation
*
typename
ChromaticTreeOperation
<
Key
,
Value
>::
Operation
*
ChromaticTreeOperation
<
Key
,
Value
>::
GetRetiredDummmy
()
{
ChromaticTreeOperation
<
Key
,
Value
>::
GetRetiredDummmy
()
{
#ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable:4640)
#endif
static
ChromaticTreeOperation
retired_dummy
;
static
ChromaticTreeOperation
retired_dummy
;
#ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(pop)
#endif
retired_dummy
.
state_
=
STATE_COMMITTED
;
retired_dummy
.
state_
=
STATE_COMMITTED
;
...
@@ -513,10 +544,10 @@ ChromaticTree(size_t capacity, Key undefined_key, Value undefined_value,
...
@@ -513,10 +544,10 @@ ChromaticTree(size_t capacity, Key undefined_key, Value undefined_value,
operation_pool_
(
2
+
5
+
2
*
capacity_
+
operation_pool_
(
2
+
5
+
2
*
capacity_
+
operation_hazard_manager_
.
GetRetiredListMaxSize
()
*
operation_hazard_manager_
.
GetRetiredListMaxSize
()
*
embb
::
base
::
Thread
::
GetThreadsMaxCount
()),
embb
::
base
::
Thread
::
GetThreadsMaxCount
()),
entry_
(
node_pool_
.
Allocate
(
undefined_key_
,
undefined_value_
,
1
,
entry_
(
node_pool_
.
Allocate
(
undefined_key_
,
undefined_value_
,
-
1
,
node_pool_
.
Allocate
(
undefined_key_
,
node_pool_
.
Allocate
(
undefined_key_
,
undefined_value_
,
undefined_value_
,
1
,
-
1
,
Operation
::
INITIAL_DUMMY
),
Operation
::
INITIAL_DUMMY
),
static_cast
<
Node
*>
(
NULL
),
static_cast
<
Node
*>
(
NULL
),
Operation
::
INITIAL_DUMMY
))
{
Operation
::
INITIAL_DUMMY
))
{
...
@@ -539,7 +570,7 @@ Get(const Key& key, Value& value) {
...
@@ -539,7 +570,7 @@ Get(const Key& key, Value& value) {
HazardNodePtr
leaf
(
GetNodeGuard
(
HIDX_LEAF
));
HazardNodePtr
leaf
(
GetNodeGuard
(
HIDX_LEAF
));
Search
(
key
,
leaf
,
parent
,
grandparent
);
Search
(
key
,
leaf
,
parent
,
grandparent
);
bool
keys_are_equal
=
!
IsSentinel
(
leaf
)
&&
bool
keys_are_equal
=
!
leaf
->
IsSentinel
(
)
&&
!
(
compare_
(
key
,
leaf
->
GetKey
())
||
!
(
compare_
(
key
,
leaf
->
GetKey
())
||
compare_
(
leaf
->
GetKey
(),
key
));
compare_
(
leaf
->
GetKey
(),
key
));
...
@@ -582,7 +613,7 @@ TryInsert(const Key& key, const Value& value, Value& old_value) {
...
@@ -582,7 +613,7 @@ TryInsert(const Key& key, const Value& value, Value& old_value) {
HazardOperationPtr
leaf_op
(
GetOperationGuard
(
HIDX_LEAF
));
HazardOperationPtr
leaf_op
(
GetOperationGuard
(
HIDX_LEAF
));
if
(
!
WeakLLX
(
leaf
,
leaf_op
))
continue
;
if
(
!
WeakLLX
(
leaf
,
leaf_op
))
continue
;
bool
keys_are_equal
=
!
IsSentinel
(
leaf
)
&&
bool
keys_are_equal
=
!
leaf
->
IsSentinel
(
)
&&
!
(
compare_
(
key
,
leaf
->
GetKey
())
||
!
(
compare_
(
key
,
leaf
->
GetKey
())
||
compare_
(
leaf
->
GetKey
(),
key
));
compare_
(
leaf
->
GetKey
(),
key
));
if
(
keys_are_equal
)
{
if
(
keys_are_equal
)
{
...
@@ -603,8 +634,11 @@ TryInsert(const Key& key, const Value& value, Value& old_value) {
...
@@ -603,8 +634,11 @@ TryInsert(const Key& key, const Value& value, Value& old_value) {
Operation
::
INITIAL_DUMMY
);
Operation
::
INITIAL_DUMMY
);
if
(
new_sibling
==
NULL
)
break
;
if
(
new_sibling
==
NULL
)
break
;
int
new_weight
=
(
IsSentinel
(
parent
))
?
1
:
(
leaf
->
GetWeight
()
-
1
);
int
new_weight
=
if
(
IsSentinel
(
leaf
)
||
compare_
(
key
,
leaf
->
GetKey
()))
{
leaf
->
IsSentinel
()
?
-
1
:
parent
->
IsSentinel
()
?
1
:
(
leaf
->
GetWeight
()
-
1
);
if
(
leaf
->
IsSentinel
()
||
compare_
(
key
,
leaf
->
GetKey
()))
{
new_parent
=
node_pool_
.
Allocate
(
leaf
->
GetKey
(),
undefined_value_
,
new_parent
=
node_pool_
.
Allocate
(
leaf
->
GetKey
(),
undefined_value_
,
new_weight
,
new_leaf
,
new_sibling
,
new_weight
,
new_leaf
,
new_sibling
,
Operation
::
INITIAL_DUMMY
);
Operation
::
INITIAL_DUMMY
);
...
@@ -685,7 +719,7 @@ TryDelete(const Key& key, Value& old_value) {
...
@@ -685,7 +719,7 @@ TryDelete(const Key& key, Value& old_value) {
Search
(
key
,
leaf
,
parent
,
grandparent
);
Search
(
key
,
leaf
,
parent
,
grandparent
);
// Reached leaf has a different key - nothing to delete
// Reached leaf has a different key - nothing to delete
if
(
IsSentinel
(
leaf
)
||
(
compare_
(
key
,
leaf
->
GetKey
())
||
if
(
leaf
->
IsSentinel
(
)
||
(
compare_
(
key
,
leaf
->
GetKey
())
||
compare_
(
leaf
->
GetKey
(),
key
)))
{
compare_
(
leaf
->
GetKey
(),
key
)))
{
old_value
=
undefined_value_
;
old_value
=
undefined_value_
;
deletion_succeeded
=
true
;
deletion_succeeded
=
true
;
...
@@ -720,8 +754,10 @@ TryDelete(const Key& key, Value& old_value) {
...
@@ -720,8 +754,10 @@ TryDelete(const Key& key, Value& old_value) {
HazardOperationPtr
leaf_op
(
GetOperationGuard
(
HIDX_LEAF
));
HazardOperationPtr
leaf_op
(
GetOperationGuard
(
HIDX_LEAF
));
if
(
!
WeakLLX
(
leaf
,
leaf_op
))
continue
;
if
(
!
WeakLLX
(
leaf
,
leaf_op
))
continue
;
int
new_weight
=
(
IsSentinel
(
grandparent
))
?
int
new_weight
=
1
:
(
parent
->
GetWeight
()
+
sibling
->
GetWeight
());
parent
->
IsSentinel
()
?
-
1
:
grandparent
->
IsSentinel
()
?
1
:
(
parent
->
GetWeight
()
+
sibling
->
GetWeight
());
new_leaf
=
node_pool_
.
Allocate
(
new_leaf
=
node_pool_
.
Allocate
(
sibling
->
GetKey
(),
sibling
->
GetValue
(),
new_weight
,
sibling
->
GetKey
(),
sibling
->
GetValue
(),
new_weight
,
...
@@ -788,9 +824,9 @@ GetUndefinedValue() const {
...
@@ -788,9 +824,9 @@ GetUndefinedValue() const {
}
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
ValuePool
>::
inline
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
ValuePool
>::
IsEmpty
()
const
{
IsEmpty
()
const
{
return
IsLeaf
(
entry_
->
GetLeft
()
);
return
entry_
->
GetLeft
()
->
IsLeaf
(
);
}
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
...
@@ -804,13 +840,13 @@ Search(const Key& key, HazardNodePtr& leaf, HazardNodePtr& parent,
...
@@ -804,13 +840,13 @@ Search(const Key& key, HazardNodePtr& leaf, HazardNodePtr& parent,
parent
.
ProtectSafe
(
entry_
);
parent
.
ProtectSafe
(
entry_
);
leaf
.
ProtectSafe
(
entry_
);
leaf
.
ProtectSafe
(
entry_
);
reached_leaf
=
IsLeaf
(
leaf
);
reached_leaf
=
leaf
->
IsLeaf
(
);
while
(
!
reached_leaf
)
{
while
(
!
reached_leaf
)
{
grandparent
.
AdoptHazard
(
parent
);
grandparent
.
AdoptHazard
(
parent
);
parent
.
AdoptHazard
(
leaf
);
parent
.
AdoptHazard
(
leaf
);
AtomicNodePtr
&
next_leaf
=
AtomicNodePtr
&
next_leaf
=
(
IsSentinel
(
leaf
)
||
compare_
(
key
,
leaf
->
GetKey
()))
?
(
leaf
->
IsSentinel
(
)
||
compare_
(
key
,
leaf
->
GetKey
()))
?
leaf
->
GetLeft
()
:
leaf
->
GetRight
();
leaf
->
GetLeft
()
:
leaf
->
GetRight
();
// Parent is protected, so we can tolerate a changing child pointer
// Parent is protected, so we can tolerate a changing child pointer
...
@@ -828,25 +864,13 @@ Search(const Key& key, HazardNodePtr& leaf, HazardNodePtr& parent,
...
@@ -828,25 +864,13 @@ Search(const Key& key, HazardNodePtr& leaf, HazardNodePtr& parent,
VERIFY_ADDRESS
(
static_cast
<
Node
*>
(
leaf
));
VERIFY_ADDRESS
(
static_cast
<
Node
*>
(
leaf
));
reached_leaf
=
IsLeaf
(
leaf
);
reached_leaf
=
leaf
->
IsLeaf
(
);
}
}
}
}
}
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
ValuePool
>::
inline
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
ValuePool
>::
IsLeaf
(
const
Node
*
node
)
const
{
return
node
->
GetLeft
()
==
NULL
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
ValuePool
>::
IsSentinel
(
const
Node
*
node
)
const
{
return
(
node
==
entry_
)
||
(
node
==
entry_
->
GetLeft
());
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
ValuePool
>::
HasChild
(
const
Node
*
parent
,
const
Node
*
child
)
const
{
HasChild
(
const
Node
*
parent
,
const
Node
*
child
)
const
{
return
(
parent
->
GetLeft
()
==
child
||
parent
->
GetRight
()
==
child
);
return
(
parent
->
GetLeft
()
==
child
||
parent
->
GetRight
()
==
child
);
}
}
...
@@ -854,7 +878,7 @@ HasChild(const Node* parent, const Node* child) const {
...
@@ -854,7 +878,7 @@ HasChild(const Node* parent, const Node* child) const {
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
ValuePool
>
void
ChromaticTree
<
Key
,
Value
,
Compare
,
ValuePool
>::
void
ChromaticTree
<
Key
,
Value
,
Compare
,
ValuePool
>::
Destruct
(
Node
*
node
)
{
Destruct
(
Node
*
node
)
{
if
(
!
IsLeaf
(
node
))
{
if
(
!
node
->
IsLeaf
(
))
{
Destruct
(
node
->
GetLeft
());
Destruct
(
node
->
GetLeft
());
Destruct
(
node
->
GetRight
());
Destruct
(
node
->
GetRight
());
}
}
...
@@ -884,7 +908,7 @@ IsBalanced(const Node* node) const {
...
@@ -884,7 +908,7 @@ IsBalanced(const Node* node) const {
// Overweight violation
// Overweight violation
bool
has_violation
=
node
->
GetWeight
()
>
1
;
bool
has_violation
=
node
->
GetWeight
()
>
1
;
if
(
!
has_violation
&&
!
IsLeaf
(
node
))
{
if
(
!
has_violation
&&
!
node
->
IsLeaf
(
))
{
const
Node
*
left
=
node
->
GetLeft
();
const
Node
*
left
=
node
->
GetLeft
();
const
Node
*
right
=
node
->
GetRight
();
const
Node
*
right
=
node
->
GetRight
();
...
@@ -994,14 +1018,14 @@ CleanUp(const Key& key) {
...
@@ -994,14 +1018,14 @@ CleanUp(const Key& key) {
parent
.
ProtectSafe
(
entry_
);
parent
.
ProtectSafe
(
entry_
);
leaf
.
ProtectSafe
(
entry_
);
leaf
.
ProtectSafe
(
entry_
);
reached_leaf
=
IsLeaf
(
leaf
);
reached_leaf
=
leaf
->
IsLeaf
(
);
while
(
!
reached_leaf
&&
!
found_violation
)
{
while
(
!
reached_leaf
&&
!
found_violation
)
{
grandgrandparent
.
AdoptHazard
(
grandparent
);
grandgrandparent
.
AdoptHazard
(
grandparent
);
grandparent
.
AdoptHazard
(
parent
);
grandparent
.
AdoptHazard
(
parent
);
parent
.
AdoptHazard
(
leaf
);
parent
.
AdoptHazard
(
leaf
);
AtomicNodePtr
&
next_leaf
=
AtomicNodePtr
&
next_leaf
=
(
IsSentinel
(
leaf
)
||
compare_
(
key
,
leaf
->
GetKey
()))
?
(
leaf
->
IsSentinel
(
)
||
compare_
(
key
,
leaf
->
GetKey
()))
?
leaf
->
GetLeft
()
:
leaf
->
GetRight
();
leaf
->
GetLeft
()
:
leaf
->
GetRight
();
// Parent is protected, so we can tolerate a changing child pointer
// Parent is protected, so we can tolerate a changing child pointer
...
@@ -1030,7 +1054,7 @@ CleanUp(const Key& key) {
...
@@ -1030,7 +1054,7 @@ CleanUp(const Key& key) {
break
;
break
;
}
}
reached_leaf
=
IsLeaf
(
leaf
);
reached_leaf
=
leaf
->
IsLeaf
(
);
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
containers_cpp/include/embb/containers/lock_free_chromatic_tree.h
View file @
028a03b5
...
@@ -33,6 +33,8 @@
...
@@ -33,6 +33,8 @@
#include <embb/base/c/errors.h>
#include <embb/base/c/errors.h>
#include <embb/base/mutex.h>
#include <embb/base/mutex.h>
#include <embb/containers/internal/hazard_pointer.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
embb
{
namespace
containers
{
namespace
containers
{
...
@@ -124,6 +126,20 @@ class ChromaticTreeNode {
...
@@ -124,6 +126,20 @@ class ChromaticTreeNode {
Node
*
GetRight
()
const
;
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
* 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
* \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
* operation. If neither left nor right child pointer is pointing to
...
@@ -169,6 +185,8 @@ class ChromaticTreeNode {
...
@@ -169,6 +185,8 @@ class ChromaticTreeNode {
const
Key
key_
;
/**< Stored key. */
const
Key
key_
;
/**< Stored key. */
const
Value
value_
;
/**< Stored value. */
const
Value
value_
;
/**< Stored value. */
const
int
weight_
;
/**< Weight of the node. */
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
left_
;
/**< Pointer to left child node. */
AtomicNodePtr
right_
;
/**< Pointer to right child node. */
AtomicNodePtr
right_
;
/**< Pointer to right child node. */
AtomicFlag
retired_
;
/**< Retired (marked for deletion) flag. */
AtomicFlag
retired_
;
/**< Retired (marked for deletion) flag. */
...
@@ -692,24 +710,6 @@ class ChromaticTree {
...
@@ -692,24 +710,6 @@ class ChromaticTree {
HazardNodePtr
&
grandparent
);
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.
* Checks whether the given node has a specified child node.
*
*
* \param[IN] parent Parent node
* \param[IN] parent Parent node
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment