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
2c905f00
authored
9 years ago
by
Danila Klimenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added a generator for the chromatic tree rebalancing routines.
parent
028a03b5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
463 additions
and
1362 deletions
+463
-1362
containers_cpp/CMakeLists.txt
+15
-1
containers_cpp/generator/CMakeLists.txt
+1
-0
containers_cpp/generator/chromatic_tree_generator.cc
+178
-0
containers_cpp/generator/chromatic_tree_operations.h
+269
-0
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-rebalance.h
+0
-1361
No files found.
containers_cpp/CMakeLists.txt
View file @
2c905f00
...
@@ -12,12 +12,25 @@ GroupSourcesMSVC(test)
...
@@ -12,12 +12,25 @@ GroupSourcesMSVC(test)
set
(
EMBB_CONTAINERS_CPP_INCLUDE_DIRS
"include"
"src"
"test"
)
set
(
EMBB_CONTAINERS_CPP_INCLUDE_DIRS
"include"
"src"
"test"
)
include_directories
(
${
EMBB_CONTAINERS_CPP_INCLUDE_DIRS
}
include_directories
(
${
EMBB_CONTAINERS_CPP_INCLUDE_DIRS
}
${
CMAKE_CURRENT_BINARY_DIR
}
/include
${
CMAKE_CURRENT_SOURCE_DIR
}
/../base_c/include
${
CMAKE_CURRENT_SOURCE_DIR
}
/../base_c/include
${
CMAKE_CURRENT_BINARY_DIR
}
/../base_c/include
${
CMAKE_CURRENT_BINARY_DIR
}
/../base_c/include
${
CMAKE_CURRENT_SOURCE_DIR
}
/../base_cpp/include
${
CMAKE_CURRENT_SOURCE_DIR
}
/../base_cpp/include
${
CMAKE_CURRENT_BINARY_DIR
}
/../base_cpp/include
)
${
CMAKE_CURRENT_BINARY_DIR
}
/../base_cpp/include
)
add_library
(
embb_containers_cpp
${
EMBB_CONTAINERS_CPP_SOURCES
}
${
EMBB_CONTAINERS_CPP_HEADERS
}
)
add_subdirectory
(
generator
)
set
(
GENERATOR_OUTPUT_DIR
${
CMAKE_CURRENT_BINARY_DIR
}
/include/embb/containers/internal
)
set
(
CHROMATIC_TREE_GENERATED_HEADER
${
GENERATOR_OUTPUT_DIR
}
/lock_free_chromatic_tree-rebalance.h
)
file
(
MAKE_DIRECTORY
${
GENERATOR_OUTPUT_DIR
}
)
add_custom_command
(
OUTPUT
${
CHROMATIC_TREE_GENERATED_HEADER
}
COMMAND chromatic_tree_generator
${
CHROMATIC_TREE_GENERATED_HEADER
}
DEPENDS chromatic_tree_generator
)
add_library
(
embb_containers_cpp
${
EMBB_CONTAINERS_CPP_SOURCES
}
${
EMBB_CONTAINERS_CPP_HEADERS
}
${
CHROMATIC_TREE_GENERATED_HEADER
}
)
target_link_libraries
(
embb_containers_cpp embb_base_cpp
)
target_link_libraries
(
embb_containers_cpp embb_base_cpp
)
if
(
BUILD_TESTS STREQUAL ON
)
if
(
BUILD_TESTS STREQUAL ON
)
...
@@ -30,4 +43,5 @@ endif()
...
@@ -30,4 +43,5 @@ endif()
install
(
DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
/include/embb
install
(
DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
/include/embb
DESTINATION include FILES_MATCHING PATTERN
"*.h"
)
DESTINATION include FILES_MATCHING PATTERN
"*.h"
)
install
(
FILES
${
CHROMATIC_TREE_GENERATED_HEADER
}
DESTINATION include/embb/containers/internal
)
install
(
TARGETS embb_containers_cpp DESTINATION lib
)
install
(
TARGETS embb_containers_cpp DESTINATION lib
)
This diff is collapsed.
Click to expand it.
containers_cpp/generator/CMakeLists.txt
0 → 100644
View file @
2c905f00
add_executable
(
chromatic_tree_generator chromatic_tree_generator.cc chromatic_tree_operations.h
)
This diff is collapsed.
Click to expand it.
containers_cpp/generator/chromatic_tree_generator.cc
0 → 100644
View file @
2c905f00
/*
* Copyright (c) 2014-2015, Siemens AG. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "chromatic_tree_operations.h"
static
const
char
INCLUDE_GUARD
[]
=
"EMBB_CONTAINERS_INTERNAL_LOCK_FREE_CHROMATIC_TREE_REBALANCE_H_"
;
static
const
char
GENERATOR_NOTICE
[]
=
"//
\n
"
"// This file was created automatically by a code generator.
\n
"
"// Any direct changes will be lost after rebuild of the project.
\n
"
"//"
;
static
const
char
RETURN_TYPE
[]
=
"embb_errors_t"
;
static
const
char
NODEARG_TYPE
[]
=
"HazardNodePtr"
;
static
const
char
LOCKARG_TYPE
[]
=
"HazardOperationPtr"
;
static
const
char
NEWNODE_TYPE
[]
=
"Node*"
;
void
PrintOperationSourceCode
(
FILE
*
file
,
const
RebalancingOperation
&
op
);
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
!=
2
)
{
fprintf
(
stderr
,
"USAGE:
\n
%s <output_file>
\n
"
,
argv
[
0
]);
return
1
;
}
const
char
*
filename
=
argv
[
1
];
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996)
#endif
FILE
*
file
=
fopen
(
filename
,
"w"
);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
if
(
file
==
NULL
)
{
fprintf
(
stderr
,
"Error: Cannot open file '%s' for writing!
\n
"
,
filename
);
return
1
;
}
// Printing header
fprintf
(
file
,
"#ifndef %s
\n
#define %s
\n\n
"
,
INCLUDE_GUARD
,
INCLUDE_GUARD
);
fprintf
(
file
,
"%s
\n\n
"
,
GENERATOR_NOTICE
);
// Printing methods code
int
num_operations
=
(
sizeof
(
REBALANCING_OPERATIONS
)
/
sizeof
(
REBALANCING_OPERATIONS
[
0
]));
for
(
int
i
=
0
;
i
<
num_operations
;
++
i
)
{
PrintOperationSourceCode
(
file
,
REBALANCING_OPERATIONS
[
i
]);
}
// Printing trailer
fprintf
(
file
,
"#endif // %s
\n
"
,
INCLUDE_GUARD
);
fclose
(
file
);
return
0
;
}
void
PrintOperationSourceCode
(
FILE
*
file
,
const
RebalancingOperation
&
op
)
{
// Method signature
fprintf
(
file
,
"%s %s("
,
RETURN_TYPE
,
op
.
name
);
// Method arguments
fprintf
(
file
,
"%s& u, %s& u_op"
,
NODEARG_TYPE
,
LOCKARG_TYPE
);
int
offset
=
static_cast
<
int
>
(
strlen
(
NODEARG_TYPE
)
+
strlen
(
op
.
name
)
+
2
);
for
(
int
i
=
0
;
i
<
op
.
num_nodes
;
++
i
)
{
fprintf
(
file
,
",
\n
%*s%s& %s, %s& %s_op"
,
offset
,
""
,
NODEARG_TYPE
,
op
.
old_nodes
[
i
].
name
,
LOCKARG_TYPE
,
op
.
old_nodes
[
i
].
name
);
}
fprintf
(
file
,
") {
\n
"
" embb_errors_t result = EMBB_NOMEM;
\n
"
);
// Define nodes
for
(
int
i
=
0
;
i
<
op
.
num_nodes
;
++
i
)
{
fprintf
(
file
,
" %s %s = NULL;
\n
"
,
NEWNODE_TYPE
,
op
.
new_nodes
[
i
].
name
);
}
fprintf
(
file
,
"
\n
"
" while (result != EMBB_SUCCESS) {
\n
"
);
// Construct new nodes
for
(
int
i
=
0
;
i
<
op
.
num_nodes
;
++
i
)
{
fprintf
(
file
,
" %s = node_pool_.Allocate(
\n
"
" %s->GetKey(), %s->GetValue(), %s,
\n
"
" %s, %s, Operation::INITIAL_DUMMY);
\n
"
" if (%s == NULL) break;
\n
"
,
op
.
new_nodes
[
i
].
name
,
op
.
new_nodes
[
i
].
orig_node
,
op
.
new_nodes
[
i
].
orig_node
,
op
.
new_nodes
[
i
].
weight
,
op
.
new_nodes
[
i
].
left
,
op
.
new_nodes
[
i
].
right
,
op
.
new_nodes
[
i
].
name
);
}
fprintf
(
file
,
"
\n
"
" HazardOperationPtr op(GetOperationGuard(HIDX_CURRENT_OP));
\n
"
" op.ProtectSafe(operation_pool_.Allocate());
\n
"
" if (op == NULL) break;
\n
"
);
// Create and fill the operation object
fprintf
(
file
,
"
\n
"
" op->SetRoot(u, u_op);
\n
"
" op->SetNewChild(nx);
\n
"
" op->SetOldNodes(%s, %s_op"
,
op
.
old_nodes
[
0
].
name
,
op
.
old_nodes
[
0
].
name
);
for
(
int
i
=
1
;
i
<
op
.
num_nodes
;
++
i
)
{
fprintf
(
file
,
",
\n
%s, %s_op"
,
op
.
old_nodes
[
i
].
name
,
op
.
old_nodes
[
i
].
name
);
}
fprintf
(
file
,
");
\n
"
);
// Execute operation
fprintf
(
file
,
"
\n
"
" bool succeeded = op->Help(GetNodeGuard(HIDX_HELPING),
\n
"
" GetOperationGuard(HIDX_HELPING));
\n
"
" op->CleanUp();
\n
"
"
\n
"
" if (!succeeded) {
\n
"
" RetireOperation(op);
\n
"
" result = EMBB_BUSY;
\n
"
" break;
\n
"
" }
\n
"
);
// Release original nodes and operations
fprintf
(
file
,
"
\n
"
" RetireOperation(u_op);
\n
"
);
for
(
int
i
=
0
;
i
<
op
.
num_nodes
;
++
i
)
{
fprintf
(
file
,
" RetireNode(%s); RetireOperation(%s_op);
\n
"
,
op
.
old_nodes
[
i
].
name
,
op
.
old_nodes
[
i
].
name
);
}
fprintf
(
file
,
"
\n
"
" result = EMBB_SUCCESS;
\n
"
" }
\n
"
);
// Delete new nodes if operation failed
fprintf
(
file
,
"
\n
"
" if (result != EMBB_SUCCESS) {
\n
"
);
for
(
int
i
=
0
;
i
<
op
.
num_nodes
;
++
i
)
{
fprintf
(
file
,
" if (%s) FreeNode(%s);
\n
"
,
op
.
new_nodes
[
i
].
name
,
op
.
new_nodes
[
i
].
name
);
}
fprintf
(
file
,
" }
\n
"
);
// Return statement
fprintf
(
file
,
"
\n
"
" return result;
\n
"
"}
\n
"
"
\n
"
);
};
This diff is collapsed.
Click to expand it.
containers_cpp/generator/chromatic_tree_operations.h
0 → 100644
View file @
2c905f00
#ifndef OPERATIONS_H
#define OPERATIONS_H
static
const
int
MAX_NODES
=
5
;
typedef
struct
{
const
char
*
name
;
}
OldNode
;
typedef
struct
{
const
char
*
name
;
const
char
*
orig_node
;
const
char
*
weight
;
const
char
*
left
;
const
char
*
right
;
}
NewNode
;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4510 4512 4610)
#endif
typedef
struct
{
const
char
*
name
;
const
int
num_nodes
;
const
OldNode
old_nodes
[
MAX_NODES
];
const
NewNode
new_nodes
[
MAX_NODES
];
}
RebalancingOperation
;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
static
const
RebalancingOperation
REBALANCING_OPERATIONS
[]
=
{
{
"BLK"
,
3
,
{
"ux"
,
"uxl"
,
"uxr"
},
{
{
"nxl"
,
"uxl"
,
"1"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nxr"
,
"uxr"
,
"1"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nx"
,
"ux"
,
"u->IsSentinel() ? 1 : ux->GetWeight() - 1"
,
"nxl"
,
"nxr"
}
}
},
{
"PUSH_L"
,
3
,
{
"ux"
,
"uxl"
,
"uxr"
},
{
{
"nxl"
,
"uxl"
,
"uxl->GetWeight() - 1"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nxr"
,
"uxr"
,
"0"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nx"
,
"ux"
,
"u->IsSentinel() ? 1 : ux->GetWeight() + 1"
,
"nxl"
,
"nxr"
}
}
},
{
"PUSH_R"
,
3
,
{
"ux"
,
"uxl"
,
"uxr"
},
{
{
"nxr"
,
"uxr"
,
"uxr->GetWeight() - 1"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nxl"
,
"uxl"
,
"0"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nx"
,
"ux"
,
"u->IsSentinel() ? 1 : ux->GetWeight() + 1"
,
"nxl"
,
"nxr"
}
}
},
{
"RB1_L"
,
2
,
{
"ux"
,
"uxl"
},
{
{
"nxr"
,
"ux"
,
"0"
,
"uxl->GetRight()"
,
"ux->GetRight()"
},
{
"nx"
,
"uxl"
,
"ux->GetWeight()"
,
"uxl->GetLeft()"
,
"nxr"
}
}
},
{
"RB1_R"
,
2
,
{
"ux"
,
"uxr"
},
{
{
"nxl"
,
"ux"
,
"0"
,
"ux->GetLeft()"
,
"uxr->GetLeft()"
},
{
"nx"
,
"uxr"
,
"ux->GetWeight()"
,
"nxl"
,
"uxr->GetRight()"
}
}
},
{
"RB2_L"
,
3
,
{
"ux"
,
"uxl"
,
"uxlr"
},
{
{
"nxl"
,
"uxl"
,
"0"
,
"uxl->GetLeft()"
,
"uxlr->GetLeft()"
},
{
"nxr"
,
"ux"
,
"0"
,
"uxlr->GetRight()"
,
"ux->GetRight()"
},
{
"nx"
,
"uxlr"
,
"ux->GetWeight()"
,
"nxl"
,
"nxr"
}
}
},
{
"RB2_R"
,
3
,
{
"ux"
,
"uxr"
,
"uxrl"
},
{
{
"nxr"
,
"uxr"
,
"0"
,
"uxrl->GetRight()"
,
"uxr->GetRight()"
},
{
"nxl"
,
"ux"
,
"0"
,
"ux->GetLeft()"
,
"uxrl->GetLeft()"
},
{
"nx"
,
"uxrl"
,
"ux->GetWeight()"
,
"nxl"
,
"nxr"
}
}
},
{
"W1_L"
,
4
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxrl"
},
{
{
"nxll"
,
"uxl"
,
"uxl->GetWeight() - 1"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nxlr"
,
"uxrl"
,
"uxrl->GetWeight() - 1"
,
"uxrl->GetLeft()"
,
"uxrl->GetRight()"
},
{
"nxl"
,
"ux"
,
"1"
,
"nxll"
,
"nxlr"
},
{
"nx"
,
"uxr"
,
"ux->GetWeight()"
,
"nxl"
,
"uxr->GetRight()"
}
}
},
{
"W1_R"
,
4
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxlr"
},
{
{
"nxrr"
,
"uxr"
,
"uxr->GetWeight() - 1"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nxrl"
,
"uxlr"
,
"uxlr->GetWeight() - 1"
,
"uxlr->GetLeft()"
,
"uxlr->GetRight()"
},
{
"nxr"
,
"ux"
,
"1"
,
"nxrl"
,
"nxrr"
},
{
"nx"
,
"uxl"
,
"ux->GetWeight()"
,
"uxl->GetLeft()"
,
"nxr"
}
}
},
{
"W2_L"
,
4
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxrl"
},
{
{
"nxll"
,
"uxl"
,
"uxl->GetWeight() - 1"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nxlr"
,
"uxrl"
,
"0"
,
"uxrl->GetLeft()"
,
"uxrl->GetRight()"
},
{
"nxl"
,
"ux"
,
"1"
,
"nxll"
,
"nxlr"
},
{
"nx"
,
"uxr"
,
"ux->GetWeight()"
,
"nxl"
,
"uxr->GetRight()"
}
}
},
{
"W2_R"
,
4
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxlr"
},
{
{
"nxrr"
,
"uxr"
,
"uxr->GetWeight() - 1"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nxrl"
,
"uxlr"
,
"0"
,
"uxlr->GetLeft()"
,
"uxlr->GetRight()"
},
{
"nxr"
,
"ux"
,
"1"
,
"nxrl"
,
"nxrr"
},
{
"nx"
,
"uxl"
,
"ux->GetWeight()"
,
"uxl->GetLeft()"
,
"nxr"
}
}
},
{
"W3_L"
,
5
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxrl"
,
"uxrll"
},
{
{
"nxlll"
,
"uxl"
,
"uxl->GetWeight() - 1"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nxll"
,
"ux"
,
"1"
,
"nxlll"
,
"uxrll->GetLeft()"
},
{
"nxlr"
,
"uxrl"
,
"1"
,
"uxrll->GetRight()"
,
"uxrl->GetRight()"
},
{
"nxl"
,
"uxrll"
,
"0"
,
"nxll"
,
"nxlr"
},
{
"nx"
,
"uxr"
,
"ux->GetWeight()"
,
"nxl"
,
"uxr->GetRight()"
}
}
},
{
"W3_R"
,
5
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxlr"
,
"uxlrr"
},
{
{
"nxrrr"
,
"uxr"
,
"uxr->GetWeight() - 1"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nxrr"
,
"ux"
,
"1"
,
"uxlrr->GetRight()"
,
"nxrrr"
},
{
"nxrl"
,
"uxlr"
,
"1"
,
"uxlr->GetLeft()"
,
"uxlrr->GetLeft()"
},
{
"nxr"
,
"uxlrr"
,
"0"
,
"nxrl"
,
"nxrr"
},
{
"nx"
,
"uxl"
,
"ux->GetWeight()"
,
"uxl->GetLeft()"
,
"nxr"
}
}
},
{
"W4_L"
,
5
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxrl"
,
"uxrlr"
},
{
{
"nxll"
,
"uxl"
,
"uxl->GetWeight() - 1"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nxrl"
,
"uxrlr"
,
"1"
,
"uxrlr->GetLeft()"
,
"uxrlr->GetRight()"
},
{
"nxl"
,
"ux"
,
"1"
,
"nxll"
,
"uxrl->GetLeft()"
},
{
"nxr"
,
"uxr"
,
"0"
,
"nxrl"
,
"uxr->GetRight()"
},
{
"nx"
,
"uxrl"
,
"ux->GetWeight()"
,
"nxl"
,
"nxr"
}
}
},
{
"W4_R"
,
5
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxlr"
,
"uxlrl"
},
{
{
"nxrr"
,
"uxr"
,
"uxr->GetWeight() - 1"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nxlr"
,
"uxlrl"
,
"1"
,
"uxlrl->GetLeft()"
,
"uxlrl->GetRight()"
},
{
"nxr"
,
"ux"
,
"1"
,
"uxlr->GetRight()"
,
"nxrr"
},
{
"nxl"
,
"uxl"
,
"0"
,
"uxl->GetLeft()"
,
"nxlr"
},
{
"nx"
,
"uxlr"
,
"ux->GetWeight()"
,
"nxl"
,
"nxr"
}
}
},
{
"W5_L"
,
4
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxrr"
},
{
{
"nxll"
,
"uxl"
,
"uxl->GetWeight() - 1"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nxl"
,
"ux"
,
"1"
,
"nxll"
,
"uxr->GetLeft()"
},
{
"nxr"
,
"uxrr"
,
"1"
,
"uxrr->GetLeft()"
,
"uxrr->GetRight()"
},
{
"nx"
,
"uxr"
,
"ux->GetWeight()"
,
"nxl"
,
"nxr"
}
}
},
{
"W5_R"
,
4
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxll"
},
{
{
"nxrr"
,
"uxr"
,
"uxr->GetWeight() - 1"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nxr"
,
"ux"
,
"1"
,
"uxl->GetRight()"
,
"nxrr"
},
{
"nxl"
,
"uxll"
,
"1"
,
"uxll->GetLeft()"
,
"uxll->GetRight()"
},
{
"nx"
,
"uxl"
,
"ux->GetWeight()"
,
"nxl"
,
"nxr"
}
}
},
{
"W6_L"
,
4
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxrl"
},
{
{
"nxll"
,
"uxl"
,
"uxl->GetWeight() - 1"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nxl"
,
"ux"
,
"1"
,
"nxll"
,
"uxrl->GetLeft()"
},
{
"nxr"
,
"uxr"
,
"1"
,
"uxrl->GetRight()"
,
"uxr->GetRight()"
},
{
"nx"
,
"uxrl"
,
"ux->GetWeight()"
,
"nxl"
,
"nxr"
}
}
},
{
"W6_R"
,
4
,
{
"ux"
,
"uxl"
,
"uxr"
,
"uxlr"
},
{
{
"nxrr"
,
"uxr"
,
"uxr->GetWeight() - 1"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nxr"
,
"ux"
,
"1"
,
"uxlr->GetRight()"
,
"nxrr"
},
{
"nxl"
,
"uxl"
,
"1"
,
"uxl->GetLeft()"
,
"uxlr->GetLeft()"
},
{
"nx"
,
"uxlr"
,
"ux->GetWeight()"
,
"nxl"
,
"nxr"
}
}
},
{
"W7"
,
3
,
{
"ux"
,
"uxl"
,
"uxr"
},
{
{
"nxl"
,
"uxl"
,
"uxl->GetWeight() - 1"
,
"uxl->GetLeft()"
,
"uxl->GetRight()"
},
{
"nxr"
,
"uxr"
,
"uxr->GetWeight() - 1"
,
"uxr->GetLeft()"
,
"uxr->GetRight()"
},
{
"nx"
,
"ux"
,
"u->IsSentinel() ? 1 : ux->GetWeight() + 1"
,
"nxl"
,
"nxr"
}
}
}
};
#endif // OPERATIONS_H
This diff is collapsed.
Click to expand it.
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-rebalance.h
deleted
100644 → 0
View file @
028a03b5
/*
* Copyright (c) 2014-2015, Siemens AG. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//
// This file was created automatically by a code generator.
// Any direct changes will be lost after rebuild of the project.
//
#ifndef EMBB_CONTAINERS_INTERNAL_LOCK_FREE_CHROMATIC_TREE_REBALANCE_H_
#define EMBB_CONTAINERS_INTERNAL_LOCK_FREE_CHROMATIC_TREE_REBALANCE_H_
embb_errors_t
BLK
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
IsSentinel
(
u
)
?
1
:
ux
->
GetWeight
()
-
1
,
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
PUSH_L
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
0
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
IsSentinel
(
u
)
?
1
:
ux
->
GetWeight
()
+
1
,
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
PUSH_R
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxr
;
Node
*
nxl
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
0
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
IsSentinel
(
u
)
?
1
:
ux
->
GetWeight
()
+
1
,
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
RB1_L
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
uxl
->
GetRight
(),
ux
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
RB1_R
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxl
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
ux
->
GetLeft
(),
uxr
->
GetLeft
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxr
,
uxr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
RB2_L
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxlr
,
HazardOperationPtr
&
uxlr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
0
,
uxl
->
GetLeft
(),
uxlr
->
GetLeft
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
uxlr
->
GetRight
(),
ux
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxlr
,
uxlr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxlr
);
RetireOperation
(
uxlr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
RB2_R
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxrl
,
HazardOperationPtr
&
uxrl_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxr
;
Node
*
nxl
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
0
,
uxrl
->
GetRight
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
ux
->
GetLeft
(),
uxrl
->
GetLeft
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxr
,
uxr_op
,
uxrl
,
uxrl_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxrl
);
RetireOperation
(
uxrl_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W1_L
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxrl
,
HazardOperationPtr
&
uxrl_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxll
;
Node
*
nxlr
;
Node
*
nxl
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxll
==
NULL
)
break
;
nxlr
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
uxrl
->
GetWeight
()
-
1
,
uxrl
->
GetLeft
(),
uxrl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxlr
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
nxlr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxrl
,
uxrl_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxrl
);
RetireOperation
(
uxrl_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxlr
)
FreeNode
(
nxlr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W1_R
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxlr
,
HazardOperationPtr
&
uxlr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxrr
;
Node
*
nxrl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrr
==
NULL
)
break
;
nxrl
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
uxlr
->
GetWeight
()
-
1
,
uxlr
->
GetLeft
(),
uxlr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxrl
,
nxrr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxlr
,
uxlr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxlr
);
RetireOperation
(
uxlr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxrl
)
FreeNode
(
nxrl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W2_L
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxrl
,
HazardOperationPtr
&
uxrl_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxll
;
Node
*
nxlr
;
Node
*
nxl
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxll
==
NULL
)
break
;
nxlr
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
0
,
uxrl
->
GetLeft
(),
uxrl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxlr
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
nxlr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxrl
,
uxrl_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxrl
);
RetireOperation
(
uxrl_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxlr
)
FreeNode
(
nxlr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W2_R
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxlr
,
HazardOperationPtr
&
uxlr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxrr
;
Node
*
nxrl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrr
==
NULL
)
break
;
nxrl
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
0
,
uxlr
->
GetLeft
(),
uxlr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxrl
,
nxrr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxlr
,
uxlr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxlr
);
RetireOperation
(
uxlr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxrl
)
FreeNode
(
nxrl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W3_L
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxrl
,
HazardOperationPtr
&
uxrl_op
,
HazardNodePtr
&
uxrll
,
HazardOperationPtr
&
uxrll_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxlll
;
Node
*
nxll
;
Node
*
nxlr
;
Node
*
nxl
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxlll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxlll
==
NULL
)
break
;
nxll
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxlll
,
uxrll
->
GetLeft
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxll
==
NULL
)
break
;
nxlr
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
1
,
uxrll
->
GetRight
(),
uxrl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxlr
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
uxrll
->
GetKey
(),
uxrll
->
GetValue
(),
0
,
nxll
,
nxlr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxrl
,
uxrl_op
,
uxrll
,
uxrll_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxrl
);
RetireOperation
(
uxrl_op
);
RetireNode
(
uxrll
);
RetireOperation
(
uxrll_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxlll
)
FreeNode
(
nxlll
);
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxlr
)
FreeNode
(
nxlr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W3_R
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxlr
,
HazardOperationPtr
&
uxlr_op
,
HazardNodePtr
&
uxlrr
,
HazardOperationPtr
&
uxlrr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxrrr
;
Node
*
nxrr
;
Node
*
nxrl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxrrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrrr
==
NULL
)
break
;
nxrr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxlrr
->
GetRight
(),
nxrrr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxrr
==
NULL
)
break
;
nxrl
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
1
,
uxlr
->
GetLeft
(),
uxlrr
->
GetLeft
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
uxlrr
->
GetKey
(),
uxlrr
->
GetValue
(),
0
,
nxrl
,
nxrr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxlr
,
uxlr_op
,
uxlrr
,
uxlrr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxlr
);
RetireOperation
(
uxlr_op
);
RetireNode
(
uxlrr
);
RetireOperation
(
uxlrr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxrrr
)
FreeNode
(
nxrrr
);
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxrl
)
FreeNode
(
nxrl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W4_L
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxrl
,
HazardOperationPtr
&
uxrl_op
,
HazardNodePtr
&
uxrlr
,
HazardOperationPtr
&
uxrlr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxll
;
Node
*
nxrl
;
Node
*
nxl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxll
==
NULL
)
break
;
nxrl
=
node_pool_
.
Allocate
(
uxrlr
->
GetKey
(),
uxrlr
->
GetValue
(),
1
,
uxrlr
->
GetLeft
(),
uxrlr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrl
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
uxrl
->
GetLeft
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
0
,
nxrl
,
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxrl
,
uxrl_op
,
uxrlr
,
uxrlr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxrl
);
RetireOperation
(
uxrl_op
);
RetireNode
(
uxrlr
);
RetireOperation
(
uxrlr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxrl
)
FreeNode
(
nxrl
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W4_R
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxlr
,
HazardOperationPtr
&
uxlr_op
,
HazardNodePtr
&
uxlrl
,
HazardOperationPtr
&
uxlrl_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxrr
;
Node
*
nxlr
;
Node
*
nxr
;
Node
*
nxl
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrr
==
NULL
)
break
;
nxlr
=
node_pool_
.
Allocate
(
uxlrl
->
GetKey
(),
uxlrl
->
GetValue
(),
1
,
uxlrl
->
GetLeft
(),
uxlrl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxlr
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxlr
->
GetRight
(),
nxrr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
0
,
uxl
->
GetLeft
(),
nxlr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxlr
,
uxlr_op
,
uxlrl
,
uxlrl_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxlr
);
RetireOperation
(
uxlr_op
);
RetireNode
(
uxlrl
);
RetireOperation
(
uxlrl_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxlr
)
FreeNode
(
nxlr
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W5_L
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxrr
,
HazardOperationPtr
&
uxrr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxll
;
Node
*
nxl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxll
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
uxr
->
GetLeft
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
uxrr
->
GetKey
(),
uxrr
->
GetValue
(),
1
,
uxrr
->
GetLeft
(),
uxrr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxrr
,
uxrr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxrr
);
RetireOperation
(
uxrr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W5_R
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxll
,
HazardOperationPtr
&
uxll_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxrr
;
Node
*
nxr
;
Node
*
nxl
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrr
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxl
->
GetRight
(),
nxrr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
uxll
->
GetKey
(),
uxll
->
GetValue
(),
1
,
uxll
->
GetLeft
(),
uxll
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxll
,
uxll_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxll
);
RetireOperation
(
uxll_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W6_L
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxrl
,
HazardOperationPtr
&
uxrl_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxll
;
Node
*
nxl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxll
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
uxrl
->
GetLeft
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
1
,
uxrl
->
GetRight
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxrl
,
uxrl_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxrl
);
RetireOperation
(
uxrl_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W6_R
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
,
HazardNodePtr
&
uxlr
,
HazardOperationPtr
&
uxlr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxrr
;
Node
*
nxr
;
Node
*
nxl
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxrr
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxlr
->
GetRight
(),
nxrr
,
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
1
,
uxl
->
GetLeft
(),
uxlr
->
GetLeft
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
,
uxlr
,
uxlr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
RetireNode
(
uxlr
);
RetireOperation
(
uxlr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
embb_errors_t
W7
(
HazardNodePtr
&
u
,
HazardOperationPtr
&
u_op
,
HazardNodePtr
&
ux
,
HazardOperationPtr
&
ux_op
,
HazardNodePtr
&
uxl
,
HazardOperationPtr
&
uxl_op
,
HazardNodePtr
&
uxr
,
HazardOperationPtr
&
uxr_op
)
{
embb_errors_t
result
=
EMBB_NOMEM
;
Node
*
nxl
;
Node
*
nxr
;
Node
*
nx
;
while
(
result
!=
EMBB_SUCCESS
)
{
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxl
==
NULL
)
break
;
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
(),
Operation
::
INITIAL_DUMMY
);
if
(
nxr
==
NULL
)
break
;
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
IsSentinel
(
u
)
?
1
:
ux
->
GetWeight
()
+
1
,
nxl
,
nxr
,
Operation
::
INITIAL_DUMMY
);
if
(
nx
==
NULL
)
break
;
HazardOperationPtr
op
(
GetOperationGuard
(
HIDX_CURRENT_OP
));
op
.
ProtectSafe
(
operation_pool_
.
Allocate
());
if
(
op
==
NULL
)
break
;
op
->
SetRoot
(
u
,
u_op
);
op
->
SetNewChild
(
nx
);
op
->
SetOldNodes
(
ux
,
ux_op
,
uxl
,
uxl_op
,
uxr
,
uxr_op
);
bool
succeeded
=
op
->
Help
(
GetNodeGuard
(
HIDX_HELPING
),
GetOperationGuard
(
HIDX_HELPING
));
op
->
CleanUp
();
if
(
!
succeeded
)
{
RetireOperation
(
op
);
result
=
EMBB_BUSY
;
break
;
}
RetireOperation
(
u_op
);
RetireNode
(
ux
);
RetireOperation
(
ux_op
);
RetireNode
(
uxl
);
RetireOperation
(
uxl_op
);
RetireNode
(
uxr
);
RetireOperation
(
uxr_op
);
result
=
EMBB_SUCCESS
;
}
if
(
result
!=
EMBB_SUCCESS
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
}
return
result
;
}
#endif // EMBB_CONTAINERS_INTERNAL_LOCK_FREE_CHROMATIC_TREE_REBALANCE_H_
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