diff --git a/containers_cpp/CMakeLists.txt b/containers_cpp/CMakeLists.txt index 014d2d3..f21408e 100644 --- a/containers_cpp/CMakeLists.txt +++ b/containers_cpp/CMakeLists.txt @@ -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) diff --git a/containers_cpp/generator/CMakeLists.txt b/containers_cpp/generator/CMakeLists.txt new file mode 100644 index 0000000..1e3bf2f --- /dev/null +++ b/containers_cpp/generator/CMakeLists.txt @@ -0,0 +1 @@ +add_executable(chromatic_tree_generator chromatic_tree_generator.cc chromatic_tree_operations.h) diff --git a/containers_cpp/generator/chromatic_tree_generator.cc b/containers_cpp/generator/chromatic_tree_generator.cc new file mode 100644 index 0000000..b2101f9 --- /dev/null +++ b/containers_cpp/generator/chromatic_tree_generator.cc @@ -0,0 +1,178 @@ +/* + * 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 +#include +#include + +#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 \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(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"); +}; diff --git a/containers_cpp/generator/chromatic_tree_operations.h b/containers_cpp/generator/chromatic_tree_operations.h new file mode 100644 index 0000000..bf61726 --- /dev/null +++ b/containers_cpp/generator/chromatic_tree_operations.h @@ -0,0 +1,269 @@ +#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 + diff --git a/containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-rebalance.h b/containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-rebalance.h deleted file mode 100644 index f6b5117..0000000 --- a/containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-rebalance.h +++ /dev/null @@ -1,1361 +0,0 @@ -/* - * 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_