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() {
}
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
];
}
...
...
@@ -393,6 +395,12 @@ void HazardPointer< GuardType >::GuardPointer(int guardPosition,
}
template
<
typename
GuardType
>
typename
HazardPointer
<
GuardType
>::
AtomicGuard
&
HazardPointer
<
GuardType
>::
GetGuardedPointer
(
int
guardPosition
)
{
return
GetHazardPointerElementForCurrentThread
().
GetGuard
(
guardPosition
);
}
template
<
typename
GuardType
>
void
HazardPointer
<
GuardType
>::
EnqueuePointerForDeletion
(
GuardType
guardedElement
)
{
GetHazardPointerElementForCurrentThread
().
AddRetired
(
guardedElement
);
...
...
containers_cpp/include/embb/containers/internal/hazard_pointer.h
View file @
2f75565c
...
...
@@ -238,6 +238,8 @@ class HazardPointerThreadEntry {
HazardPointerThreadEntry
&
operator
=
(
const
HazardPointerThreadEntry
&
);
public
:
typedef
embb
::
base
::
Atomic
<
GuardType
>
AtomicGuard
;
/**
* Checks if current thread is active (with respect to participating in hazard
* pointer management)
...
...
@@ -318,7 +320,7 @@ class HazardPointerThreadEntry {
* Gets the guard at the specified position.
* Positions are numbered, beginning with 0.
*/
GuardType
GetGuard
(
AtomicGuard
&
GetGuard
(
int
pos
/**< [IN] Position of the guard */
)
const
;
...
...
@@ -467,6 +469,8 @@ class HazardPointer {
can be deleted*/
);
public
:
typedef
typename
HazardPointerThreadEntry_t
::
AtomicGuard
AtomicGuard
;
/**
* Gets the capacity of one retired list
*
...
...
@@ -516,6 +520,9 @@ class HazardPointer {
* Guards \c guardedElement with the guard at position \c guardPosition
*/
void
GuardPointer
(
int
guardPosition
,
GuardType
guardedElement
);
AtomicGuard
&
GetGuardedPointer
(
int
guardPosition
);
/**
* Enqueue a pointer for deletion. It is added to the retired list and
* 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 @@
#include <stddef.h>
#include <functional>
#include <embb/base/c/errors.h>
#include <embb/base/mutex.h>
#include <embb/containers/internal/hazard_pointer.h>
...
...
@@ -70,6 +71,7 @@ class ChromaticTreeNode {
*
* \param[IN] key Key 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
);
...
...
@@ -126,6 +128,75 @@ class ChromaticTreeNode {
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
test
{
...
...
@@ -301,29 +372,20 @@ class ChromaticTree {
*/
typedef
embb
::
base
::
Atomic
<
NodePtr
>
AtomicNodePtr
;
typedef
internal
::
UniqueHazardGuard
<
NodePtr
>
HazardNodePtr
;
typedef
embb
::
base
::
UniqueLock
<
embb
::
base
::
Mutex
>
UniqueLock
;
/**
* 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.
*
* \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.
*
* \param[IN] key Key to be searched for
* \param[IN,OUT] leaf Reference to 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
...
...
@@ -335,8 +397,8 @@ class ChromaticTree {
* \param[IN,OUT] parent Reference to the parent 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
,
NodePtr
&
grandparent
);
void
Search
(
const
Key
&
key
,
HazardNodePtr
&
leaf
,
Hazard
NodePtr
&
parent
,
Hazard
NodePtr
&
grandparent
);
/**
* Checks whether the given node is a leaf.
...
...
@@ -415,8 +477,11 @@ class ChromaticTree {
bool
IsBalanced
()
const
;
bool
IsBalanced
(
const
NodePtr
&
node
)
const
;
void
RemoveNode
(
const
NodePtr
&
node
)
{
node_hazard_manager_
.
EnqueuePointerForDeletion
(
node
);
void
RetireHazardousNode
(
HazardNodePtr
&
node
,
UniqueLock
&
node_lock
)
{
node
->
Retire
();
node_lock
.
Unlock
();
NodePtr
node_to_delete
=
node
.
ReleaseHazard
();
node_hazard_manager_
.
EnqueuePointerForDeletion
(
node_to_delete
);
}
/**
...
...
@@ -440,16 +505,22 @@ class ChromaticTree {
/**
* 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
,
const
NodePtr
&
uxxx
);
bool
OverweightLeft
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxx
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxxl
,
const
NodePtr
&
uxxr
,
const
bool
&
uxx_is_left
);
bool
OverweightRight
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxx
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxxl
,
const
NodePtr
&
uxxr
,
const
bool
&
uxx_is_right
);
embb_errors_t
Rebalance
(
HazardNodePtr
&
u
,
HazardNodePtr
&
ux
,
HazardNodePtr
&
uxx
,
HazardNodePtr
&
uxxx
);
embb_errors_t
OverweightLeft
(
HazardNodePtr
&
u
,
UniqueLock
&
u_lock
,
HazardNodePtr
&
ux
,
UniqueLock
&
ux_lock
,
HazardNodePtr
&
uxx
,
UniqueLock
&
uxx_lock
,
HazardNodePtr
&
uxl
,
HazardNodePtr
&
uxr
,
HazardNodePtr
&
uxxl
,
UniqueLock
&
uxxl_lock
,
HazardNodePtr
&
uxxr
,
bool
uxx_is_left
);
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
// tree rotations. It is generated automatically and must be included
...
...
@@ -466,7 +537,7 @@ class ChromaticTree {
const
Compare
compare_
;
/**< Comparator object for the keys */
size_t
capacity_
;
/**< User-requested capacity of the tree */
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 */
/**
...
...
containers_cpp/test/tree_test-inl.h
View file @
2f75565c
...
...
@@ -66,11 +66,11 @@ TreeTest<Tree>::TreeTest()
Add
(
&
TreeTest
::
TreeTestConcurrentGet_ReaderMethod
,
this
,
NUM_TEST_THREADS
/
2
,
NUM_ITERATIONS
).
Post
(
&
TreeTest
::
TreeTestConcurrentGet_Post
,
this
);
//
CreateUnit("TreeTestBalance").
//
Pre(&TreeTest::TreeTestBalance_Pre, this).
//
Add(&TreeTest::TreeTestBalance_ThreadMethod, this,
//
NUM_TEST_THREADS, 1).
//
Post(&TreeTest::TreeTestBalance_Post, this);
CreateUnit
(
"TreeTestBalance"
).
Pre
(
&
TreeTest
::
TreeTestBalance_Pre
,
this
).
Add
(
&
TreeTest
::
TreeTestBalance_ThreadMethod
,
this
,
NUM_TEST_THREADS
,
1
).
Post
(
&
TreeTest
::
TreeTestBalance_Post
,
this
);
}
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