Commit 2c905f00 by Danila Klimenko

Added a generator for the chromatic tree rebalancing routines.

parent 028a03b5
......@@ -12,12 +12,25 @@ GroupSourcesMSVC(test)
set (EMBB_CONTAINERS_CPP_INCLUDE_DIRS "include" "src" "test")
include_directories(${EMBB_CONTAINERS_CPP_INCLUDE_DIRS}
${CMAKE_CURRENT_BINARY_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/../base_c/include
${CMAKE_CURRENT_BINARY_DIR}/../base_c/include
${CMAKE_CURRENT_SOURCE_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)
if (BUILD_TESTS STREQUAL ON)
......@@ -30,4 +43,5 @@ endif()
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/embb
DESTINATION include FILES_MATCHING PATTERN "*.h")
install(FILES ${CHROMATIC_TREE_GENERATED_HEADER} DESTINATION include/embb/containers/internal)
install(TARGETS embb_containers_cpp DESTINATION lib)
add_executable(chromatic_tree_generator chromatic_tree_generator.cc chromatic_tree_operations.h)
/*
* 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");
};
#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
/*
* 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_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment