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
2f75565c
authored
May 12, 2015
by
Danila Klimenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chromatic_tree: Fine-grained locking implementation (complete with rebalancing)
parent
871b5391
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
119 additions
and
33 deletions
+119
-33
containers_cpp/include/embb/containers/internal/hazard_pointer-inl.h
+9
-1
containers_cpp/include/embb/containers/internal/hazard_pointer.h
+8
-1
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-inl.h
+0
-0
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-rebalance.h
+0
-0
containers_cpp/include/embb/containers/lock_free_chromatic_tree.h
+97
-26
containers_cpp/test/tree_test-inl.h
+5
-5
No files found.
containers_cpp/include/embb/containers/internal/hazard_pointer-inl.h
View file @
2f75565c
...
@@ -182,7 +182,9 @@ HazardPointerThreadEntry<GuardType>::~HazardPointerThreadEntry() {
...
@@ -182,7 +182,9 @@ HazardPointerThreadEntry<GuardType>::~HazardPointerThreadEntry() {
}
}
template
<
typename
GuardType
>
template
<
typename
GuardType
>
GuardType
HazardPointerThreadEntry
<
GuardType
>::
GetGuard
(
int
pos
)
const
{
typename
HazardPointerThreadEntry
<
GuardType
>::
AtomicGuard
&
HazardPointerThreadEntry
<
GuardType
>::
GetGuard
(
int
pos
)
const
{
assert
(
pos
>=
0
&&
pos
<
guards_per_thread
);
return
guarded_pointers
[
pos
];
return
guarded_pointers
[
pos
];
}
}
...
@@ -393,6 +395,12 @@ void HazardPointer< GuardType >::GuardPointer(int guardPosition,
...
@@ -393,6 +395,12 @@ void HazardPointer< GuardType >::GuardPointer(int guardPosition,
}
}
template
<
typename
GuardType
>
template
<
typename
GuardType
>
typename
HazardPointer
<
GuardType
>::
AtomicGuard
&
HazardPointer
<
GuardType
>::
GetGuardedPointer
(
int
guardPosition
)
{
return
GetHazardPointerElementForCurrentThread
().
GetGuard
(
guardPosition
);
}
template
<
typename
GuardType
>
void
HazardPointer
<
GuardType
>::
EnqueuePointerForDeletion
(
void
HazardPointer
<
GuardType
>::
EnqueuePointerForDeletion
(
GuardType
guardedElement
)
{
GuardType
guardedElement
)
{
GetHazardPointerElementForCurrentThread
().
AddRetired
(
guardedElement
);
GetHazardPointerElementForCurrentThread
().
AddRetired
(
guardedElement
);
...
...
containers_cpp/include/embb/containers/internal/hazard_pointer.h
View file @
2f75565c
...
@@ -238,6 +238,8 @@ class HazardPointerThreadEntry {
...
@@ -238,6 +238,8 @@ class HazardPointerThreadEntry {
HazardPointerThreadEntry
&
operator
=
(
const
HazardPointerThreadEntry
&
);
HazardPointerThreadEntry
&
operator
=
(
const
HazardPointerThreadEntry
&
);
public
:
public
:
typedef
embb
::
base
::
Atomic
<
GuardType
>
AtomicGuard
;
/**
/**
* Checks if current thread is active (with respect to participating in hazard
* Checks if current thread is active (with respect to participating in hazard
* pointer management)
* pointer management)
...
@@ -318,7 +320,7 @@ class HazardPointerThreadEntry {
...
@@ -318,7 +320,7 @@ class HazardPointerThreadEntry {
* Gets the guard at the specified position.
* Gets the guard at the specified position.
* Positions are numbered, beginning with 0.
* Positions are numbered, beginning with 0.
*/
*/
GuardType
GetGuard
(
AtomicGuard
&
GetGuard
(
int
pos
int
pos
/**< [IN] Position of the guard */
)
const
;
/**< [IN] Position of the guard */
)
const
;
...
@@ -467,6 +469,8 @@ class HazardPointer {
...
@@ -467,6 +469,8 @@ class HazardPointer {
can be deleted*/
);
can be deleted*/
);
public
:
public
:
typedef
typename
HazardPointerThreadEntry_t
::
AtomicGuard
AtomicGuard
;
/**
/**
* Gets the capacity of one retired list
* Gets the capacity of one retired list
*
*
...
@@ -516,6 +520,9 @@ class HazardPointer {
...
@@ -516,6 +520,9 @@ class HazardPointer {
* Guards \c guardedElement with the guard at position \c guardPosition
* Guards \c guardedElement with the guard at position \c guardPosition
*/
*/
void
GuardPointer
(
int
guardPosition
,
GuardType
guardedElement
);
void
GuardPointer
(
int
guardPosition
,
GuardType
guardedElement
);
AtomicGuard
&
GetGuardedPointer
(
int
guardPosition
);
/**
/**
* Enqueue a pointer for deletion. It is added to the retired list and
* Enqueue a pointer for deletion. It is added to the retired list and
* deleted when no thread accesses it anymore.
* deleted when no thread accesses it anymore.
...
...
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-inl.h
View file @
2f75565c
This diff is collapsed.
Click to expand it.
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-rebalance.h
View file @
2f75565c
This diff is collapsed.
Click to expand it.
containers_cpp/include/embb/containers/lock_free_chromatic_tree.h
View file @
2f75565c
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include <stddef.h>
#include <stddef.h>
#include <functional>
#include <functional>
#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>
...
@@ -70,6 +71,7 @@ class ChromaticTreeNode {
...
@@ -70,6 +71,7 @@ class ChromaticTreeNode {
*
*
* \param[IN] key Key of the new node
* \param[IN] key Key of the new node
* \param[IN] value Value of the new node
* \param[IN] value Value of the new node
* \param[IN] weight Weight of the new node
*/
*/
ChromaticTreeNode
(
const
Key
&
key
,
const
Value
&
value
,
const
int
weight
=
1
);
ChromaticTreeNode
(
const
Key
&
key
,
const
Value
&
value
,
const
int
weight
=
1
);
...
@@ -126,6 +128,75 @@ class ChromaticTreeNode {
...
@@ -126,6 +128,75 @@ class ChromaticTreeNode {
embb
::
base
::
Mutex
mutex_
;
embb
::
base
::
Mutex
mutex_
;
};
};
template
<
typename
GuardedType
>
class
UniqueHazardGuard
{
public
:
typedef
embb
::
base
::
Atomic
<
GuardedType
>
AtomicGuard
;
UniqueHazardGuard
(
AtomicGuard
&
guard
,
const
GuardedType
&
undefined_guard
)
:
guard_
(
guard
),
undefined_guard_
(
undefined_guard
),
active_
(
guard_
.
Load
()
==
undefined_guard_
)
{}
~
UniqueHazardGuard
()
{
if
(
active_
)
SetUndefinedGuard
();
}
bool
ProtectHazard
(
const
AtomicGuard
&
hazard
)
{
// Read the hazard and store it into the guard
guard_
=
hazard
.
Load
();
// Check whether the guard is valid
active_
=
(
guard_
.
Load
()
==
hazard
.
Load
());
// Clear the guard if it is invalid
if
(
!
active_
)
SetUndefinedGuard
();
return
active_
;
}
bool
IsActive
()
const
{
return
active_
;
}
operator
GuardedType
()
const
{
assert
(
active_
==
true
);
return
guard_
.
Load
();
}
GuardedType
operator
->
()
const
{
assert
(
active_
==
true
);
return
guard_
.
Load
();
}
void
AdoptGuard
(
const
UniqueHazardGuard
<
GuardedType
>&
other
)
{
guard_
=
other
.
guard_
.
Load
();
active_
=
other
.
active_
;
}
GuardedType
ReleaseHazard
()
{
assert
(
active_
==
true
);
GuardedType
released_hazard
=
guard_
.
Load
();
SetUndefinedGuard
();
active_
=
false
;
return
released_hazard
;
}
private
:
void
SetUndefinedGuard
()
{
guard_
=
undefined_guard_
;
}
// Non-copyable
UniqueHazardGuard
(
const
UniqueHazardGuard
<
GuardedType
>&
);
UniqueHazardGuard
<
GuardedType
>&
operator
=
(
const
UniqueHazardGuard
<
GuardedType
>&
);
AtomicGuard
&
guard_
;
GuardedType
undefined_guard_
;
bool
active_
;
};
}
// namespace internal
}
// namespace internal
namespace
test
{
namespace
test
{
...
@@ -301,29 +372,20 @@ class ChromaticTree {
...
@@ -301,29 +372,20 @@ class ChromaticTree {
*/
*/
typedef
embb
::
base
::
Atomic
<
NodePtr
>
AtomicNodePtr
;
typedef
embb
::
base
::
Atomic
<
NodePtr
>
AtomicNodePtr
;
typedef
internal
::
UniqueHazardGuard
<
NodePtr
>
HazardNodePtr
;
typedef
embb
::
base
::
UniqueLock
<
embb
::
base
::
Mutex
>
UniqueLock
;
typedef
embb
::
base
::
UniqueLock
<
embb
::
base
::
Mutex
>
UniqueLock
;
/**
/**
* Follows a path from the root of the tree to some leaf searching for the
* Follows a path from the root of the tree to some leaf searching for the
* given key (the leaf found by this method may or may not contain the given
* given key (the leaf found by this method may or may not contain the given
* key). Returns the reached leaf.
*
* \param[IN] key Key to be searched for
* \param[IN,OUT] leaf Reference to the reached leaf
*/
void
Search
(
const
Key
&
key
,
NodePtr
&
leaf
);
/**
* Follows a path from the root of the tree to some leaf searching for the
* given key (the leaf found by this method may or may not contain the given
* key). Returns the reached leaf together with its ancestors.
* key). Returns the reached leaf together with its ancestors.
*
*
* \param[IN] key Key to be searched for
* \param[IN] key Key to be searched for
* \param[IN,OUT] leaf Reference to the reached leaf
* \param[IN,OUT] leaf Reference to the reached leaf
* \param[IN,OUT] parent Reference to the parent of the reached leaf
* \param[IN,OUT] parent Reference to the parent of the reached leaf
*/
*/
void
Search
(
const
Key
&
key
,
NodePtr
&
leaf
,
NodePtr
&
parent
);
void
Search
(
const
Key
&
key
,
HazardNodePtr
&
leaf
,
Hazard
NodePtr
&
parent
);
/**
/**
* Follows a path from the root of the tree to some leaf searching for the
* Follows a path from the root of the tree to some leaf searching for the
...
@@ -335,8 +397,8 @@ class ChromaticTree {
...
@@ -335,8 +397,8 @@ class ChromaticTree {
* \param[IN,OUT] parent Reference to the parent of the reached leaf
* \param[IN,OUT] parent Reference to the parent of the reached leaf
* \param[IN,OUT] grandparent Reference to the grandparent of the reached leaf
* \param[IN,OUT] grandparent Reference to the grandparent of the reached leaf
*/
*/
void
Search
(
const
Key
&
key
,
NodePtr
&
leaf
,
NodePtr
&
parent
,
void
Search
(
const
Key
&
key
,
HazardNodePtr
&
leaf
,
Hazard
NodePtr
&
parent
,
NodePtr
&
grandparent
);
Hazard
NodePtr
&
grandparent
);
/**
/**
* Checks whether the given node is a leaf.
* Checks whether the given node is a leaf.
...
@@ -415,8 +477,11 @@ class ChromaticTree {
...
@@ -415,8 +477,11 @@ class ChromaticTree {
bool
IsBalanced
()
const
;
bool
IsBalanced
()
const
;
bool
IsBalanced
(
const
NodePtr
&
node
)
const
;
bool
IsBalanced
(
const
NodePtr
&
node
)
const
;
void
RemoveNode
(
const
NodePtr
&
node
)
{
void
RetireHazardousNode
(
HazardNodePtr
&
node
,
UniqueLock
&
node_lock
)
{
node_hazard_manager_
.
EnqueuePointerForDeletion
(
node
);
node
->
Retire
();
node_lock
.
Unlock
();
NodePtr
node_to_delete
=
node
.
ReleaseHazard
();
node_hazard_manager_
.
EnqueuePointerForDeletion
(
node_to_delete
);
}
}
/**
/**
...
@@ -440,16 +505,22 @@ class ChromaticTree {
...
@@ -440,16 +505,22 @@ class ChromaticTree {
/**
/**
* Next block of methods is used internally to keep the balance of the tree.
* Next block of methods is used internally to keep the balance of the tree.
*/
*/
bool
Rebalance
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxx
,
embb_errors_t
Rebalance
(
HazardNodePtr
&
u
,
HazardNodePtr
&
ux
,
const
NodePtr
&
uxxx
);
HazardNodePtr
&
uxx
,
HazardNodePtr
&
uxxx
);
bool
OverweightLeft
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxx
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
embb_errors_t
OverweightLeft
(
HazardNodePtr
&
u
,
UniqueLock
&
u_lock
,
const
NodePtr
&
uxxl
,
const
NodePtr
&
uxxr
,
HazardNodePtr
&
ux
,
UniqueLock
&
ux_lock
,
const
bool
&
uxx_is_left
);
HazardNodePtr
&
uxx
,
UniqueLock
&
uxx_lock
,
bool
OverweightRight
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxx
,
HazardNodePtr
&
uxl
,
HazardNodePtr
&
uxr
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
HazardNodePtr
&
uxxl
,
UniqueLock
&
uxxl_lock
,
const
NodePtr
&
uxxl
,
const
NodePtr
&
uxxr
,
HazardNodePtr
&
uxxr
,
bool
uxx_is_left
);
const
bool
&
uxx_is_right
);
embb_errors_t
OverweightRight
(
HazardNodePtr
&
u
,
UniqueLock
&
u_lock
,
HazardNodePtr
&
ux
,
UniqueLock
&
ux_lock
,
HazardNodePtr
&
uxx
,
UniqueLock
&
uxx_lock
,
HazardNodePtr
&
uxl
,
HazardNodePtr
&
uxr
,
HazardNodePtr
&
uxxl
,
HazardNodePtr
&
uxxr
,
UniqueLock
&
uxxr_lock
,
bool
uxx_is_right
);
// The following included header contains the class methods implementing
// The following included header contains the class methods implementing
// tree rotations. It is generated automatically and must be included
// tree rotations. It is generated automatically and must be included
...
@@ -466,7 +537,7 @@ class ChromaticTree {
...
@@ -466,7 +537,7 @@ class ChromaticTree {
const
Compare
compare_
;
/**< Comparator object for the keys */
const
Compare
compare_
;
/**< Comparator object for the keys */
size_t
capacity_
;
/**< User-requested capacity of the tree */
size_t
capacity_
;
/**< User-requested capacity of the tree */
NodePool
node_pool_
;
/**< Comparator object for the keys */
NodePool
node_pool_
;
/**< Comparator object for the keys */
NodePtr
entry_
;
/**< Pointer to the sentinel node used as
AtomicNodePtr
entry_
;
/**< Pointer to the sentinel node used as
* the entry point into the tree */
* the entry point into the tree */
/**
/**
...
...
containers_cpp/test/tree_test-inl.h
View file @
2f75565c
...
@@ -66,11 +66,11 @@ TreeTest<Tree>::TreeTest()
...
@@ -66,11 +66,11 @@ TreeTest<Tree>::TreeTest()
Add
(
&
TreeTest
::
TreeTestConcurrentGet_ReaderMethod
,
this
,
Add
(
&
TreeTest
::
TreeTestConcurrentGet_ReaderMethod
,
this
,
NUM_TEST_THREADS
/
2
,
NUM_ITERATIONS
).
NUM_TEST_THREADS
/
2
,
NUM_ITERATIONS
).
Post
(
&
TreeTest
::
TreeTestConcurrentGet_Post
,
this
);
Post
(
&
TreeTest
::
TreeTestConcurrentGet_Post
,
this
);
//
CreateUnit("TreeTestBalance").
CreateUnit
(
"TreeTestBalance"
).
//
Pre(&TreeTest::TreeTestBalance_Pre, this).
Pre
(
&
TreeTest
::
TreeTestBalance_Pre
,
this
).
//
Add(&TreeTest::TreeTestBalance_ThreadMethod, this,
Add
(
&
TreeTest
::
TreeTestBalance_ThreadMethod
,
this
,
//
NUM_TEST_THREADS, 1).
NUM_TEST_THREADS
,
1
).
//
Post(&TreeTest::TreeTestBalance_Post, this);
Post
(
&
TreeTest
::
TreeTestBalance_Post
,
this
);
}
}
template
<
typename
Tree
>
template
<
typename
Tree
>
...
...
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