diff options
| author | rajdakin <rajdakin@gmail.com> | 2023-12-31 15:49:57 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-31 15:49:57 +0100 |
| commit | 5e9e1faedc97194e46f3fb4b3665ec416ce7efbf (patch) | |
| tree | 27d345328502d82ede6c58e3d181d1f682bab255 /src/tools | |
| parent | dba6a88341bacbf52d0f0c37117a04164afce9fa (diff) | |
| download | box64-5e9e1faedc97194e46f3fb4b3665ec416ce7efbf.tar.gz box64-5e9e1faedc97194e46f3fb4b3665ec416ce7efbf.zip | |
[MEMORY] Switched from a sparse array to a red-black tree (#1180)
* [MEMORY] Switched from a sparse array to an RB tree * [RBTREE] Fixed the Android build
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/rbtree.c | 894 | ||||
| -rw-r--r-- | src/tools/rcfile.c | 4 |
2 files changed, 896 insertions, 2 deletions
diff --git a/src/tools/rbtree.c b/src/tools/rbtree.c new file mode 100644 index 00000000..c79d1089 --- /dev/null +++ b/src/tools/rbtree.c @@ -0,0 +1,894 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#ifdef RBTREE_TEST +#define customMalloc malloc +#define customFree free +#else +#include "custommem.h" +#include "debug.h" +#include "rbtree.h" +#endif + +typedef struct rbnode { + struct rbnode *left, *right, *parent; + uintptr_t start, end; + uint8_t meta; + uint8_t data; +} rbnode; + +typedef struct rbtree { + rbnode *root; + int is_unstable; +} rbtree; + +rbtree* init_rbtree() { + rbtree* tree = customMalloc(sizeof(rbtree)); + tree->root = NULL; + tree->is_unstable = 0; + return tree; +} + +void delete_rbnode(rbnode *root) { + if (!root) return; + delete_rbnode(root->left); + delete_rbnode(root->right); + customFree(root); +} +void delete_rbtree(rbtree *tree) { + delete_rbnode(tree->root); + customFree(tree); +} + +#define IS_LEFT 0x1 +#define IS_BLACK 0x2 + +// Make sure prev is either the rightmost node before start or the leftmost range after start +int add_range_next_to(rbtree *tree, rbnode *prev, uintptr_t start, uintptr_t end, uint8_t data) { +// printf("Adding %lX-%lX:%hhX next to %p\n", start, end, data, prev); + rbnode *node = customMalloc(sizeof(*node)); + if (!node) return -1; + node->start = start; + node->end = end; + node->data = data; + node->left = NULL; + node->right = NULL; + + if (tree->is_unstable) { + printf_log(LOG_NONE, "Warning, unstable Red-Black tree; trying to add a node anyways\n"); + } + tree->is_unstable = 1; + + if (!tree->root) { + node->parent = NULL; + node->meta = IS_BLACK; + tree->root = node; + tree->is_unstable = 0; + return 0; + } + + node->parent = prev; + if (prev->start < start) { + prev->right = node; + node->meta = 0; + } else { + prev->left = node; + node->meta = IS_LEFT; + } + + while (!(node->meta & IS_BLACK)) { + if (!node->parent) { + node->meta = IS_BLACK; + tree->root = node; + tree->is_unstable = 0; + return 0; + } + if (node->parent->meta & IS_BLACK) { + tree->is_unstable = 0; + return 0; + } + if (!node->parent->parent) { + tree->is_unstable = 0; + return 0; // Cannot happen as the root is black, unless the tree is unstable + } + if (node->parent->meta & IS_LEFT) { + if (node->parent->parent->right && !(node->parent->parent->right->meta & IS_BLACK)) { + node->parent->meta |= IS_BLACK; + node = node->parent->parent; + node->meta &= ~IS_BLACK; + node->right->meta |= IS_BLACK; + } else { + if (!(node->meta & IS_LEFT)) { + rbnode *y, *z; + y = node; + z = y->parent; + // ((Bz->left), Rz, ((By->left), Ry, (By->right))) + // y = RED, rchild of z + // z = RED, child of z->parent + // target = (((Bz->left), Rz, (By->left)), Ry, (By->right)) + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + y->meta = z->meta; // red + same side as z + z->meta = IS_LEFT; // red + left + y->parent = z->parent; + z->parent = y; + z->right = y->left; + y->left = z; + if (z->right) { + z->right->meta &= ~IS_LEFT; + z->right->parent = z; + } + node = z; + } + rbnode *y, *z; + y = node->parent; + z = y->parent; + // (((Rnode), Ry, (By->right)), Bz, (Bz->right)) + // node = RED, lchild of y + // y = RED, lchild of z + // z = BLACK, child of z->parent OR ROOT + // target = ((Rnode), By, ((By->right), Rz, (Bz->right))) + if (z->parent) { + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + } + y->meta = z->meta; // black + same side as z + z->meta = 0; // red + right + y->parent = z->parent; + z->parent = y; + z->left = y->right; + y->right = z; + if (z->left) { + z->left->meta |= IS_LEFT; + z->left->parent = z; + } + if (!y->parent) tree->root = y; + tree->is_unstable = 0; + return 0; + } + } else { + if (node->parent->parent->left && !(node->parent->parent->left->meta & IS_BLACK)) { + node->parent->meta |= IS_BLACK; + node = node->parent->parent; + node->meta &= ~IS_BLACK; + node->left->meta |= IS_BLACK; + } else { + if (node->meta & IS_LEFT) { + rbnode *y, *z; + y = node; + z = y->parent; + // (((By->left), Ry, (By->right)), Rz, (Bz->right)) + // y = RED, lchild of z + // z = RED, child of z->parent + // target = ((By->left), Ry, ((By->right), Rz, (Bz->right))) + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + y->meta = z->meta; // red + same side as z + z->meta = 0; // red + right + y->parent = z->parent; + z->parent = y; + z->left = y->right; + y->right = z; + if (z->left) { + z->left->meta |= IS_LEFT; + z->left->parent = z; + } + node = z; + } + rbnode *y, *z; + y = node->parent; + z = y->parent; + // ((Bz->left), Bz, ((By->left), Ry, (Rnode))) + // node = RED, rchild of y + // y = RED, rchild of z + // z = BLACK, child of z->parent OR ROOT + // target = (((Bz->left), Rz, (By->left)), By, (Rnode)) + if (z->parent) { + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + } + y->meta = z->meta; // black + same side as z + z->meta = IS_LEFT; // red + left + y->parent = z->parent; + z->parent = y; + z->right = y->left; + y->left = z; + if (z->right) { + z->right->meta &= ~IS_LEFT; + z->right->parent = z; + } + if (!y->parent) tree->root = y; + tree->is_unstable = 0; + return 0; + } + } + } + tree->is_unstable = 0; + return -1; // unreachable +} +int add_range(rbtree *tree, uintptr_t start, uintptr_t end, uint8_t data) { +// printf("add_range\n"); + rbnode *cur = tree->root, *prev = NULL; + while (cur) { + prev = cur; + if (cur->start < start) cur = cur->right; + else cur = cur->left; + } + return add_range_next_to(tree, prev, start, end, data); +} + +rbnode *find_addr(rbtree *tree, uintptr_t addr) { + rbnode *node = tree->root; + while (node) { + if ((node->start <= addr) && (node->end > addr)) return node; + if (addr < node->start) node = node->left; + else node = node->right; + } + return NULL; +} + +// node must be a valid node in the tree +int remove_node(rbtree *tree, rbnode *node) { +// printf("Removing %p\n", node); print_rbtree(tree); fflush(stdout); + if (tree->is_unstable) { + printf_log(LOG_NONE, "Warning, unstable Red-Black tree; trying to add a node anyways\n"); + } + tree->is_unstable = 1; + + if (node->left && node->right) { + // Swap node and its successor + // Do NOT free the successor as a reference to it can exist + rbnode *cur = node->right, *prev; + while (cur) { + prev = cur; + cur = cur->left; + } + // Swap the position of node and prev != node + uint8_t tmp8 = node->meta; + node->meta = prev->meta; + prev->meta = tmp8; + prev->left = node->left; + node->left = NULL; + if (prev->left) prev->left->parent = prev; + if (node->meta & IS_LEFT) { + cur = node->parent; + node->parent = prev->parent; + prev->parent = cur; + cur = node->right; + node->right = prev->right; + prev->right = cur; + if (cur) cur->parent = prev; + } else { + node->right = prev->right; + prev->right = node; + prev->parent = node->parent; + node->parent = prev; + } + if (node->right) node->right->parent = node; // Should be overriden later + if (!prev->parent) { + tree->root = prev; // prev is already black + } else if (prev->meta & IS_LEFT) { + prev->parent->left = prev; + } else { + prev->parent->right = prev; + } + } + rbnode *child = node->left ? node->left : node->right, *parent = node->parent; + if (child) { + child->parent = parent; + if (!parent) { + tree->root = child; + child->meta |= IS_BLACK; // Needs to be an or + tree->is_unstable = 0; + return 0; + } else if (node->meta & IS_LEFT) { + child->meta |= IS_LEFT; + parent->left = child; + } else { + child->meta &= ~IS_LEFT; + parent->right = child; + } + } else { + if (!parent) { + tree->root = NULL; + customFree(node); + tree->is_unstable = 0; + return 0; + } else if (node->meta & IS_LEFT) { + parent->left = NULL; + } else { + parent->right = NULL; + } + } + // Node has been removed, now to fix the tree + if (!(node->meta & IS_BLACK)) { + customFree(node); + tree->is_unstable = 0; + return 0; + } + customFree(node); + + // Add a black node before child + // Notice that the sibling cannot be NULL. + while (parent && (!child || (child->meta & IS_BLACK))) { + if ((child && child->meta & IS_LEFT) || (!child && !parent->left)) { + node = parent->right; + if (!(node->meta & IS_BLACK)) { + // rotate === + rbnode *y, *z; + y = node; + z = parent; + // ((Bchild), Bz, ((y->left), Ry, (y->right))) + // y = RED, rchild of z + // z = BLACK, child of z->parent OR ROOT + // target = (((Bchild), Rz, (y->left)), By, (y->right)) + if (z->parent) { + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + } else { + tree->root = y; + } + y->meta = z->meta; // black + same side as z + z->meta = IS_LEFT; // red + left + y->parent = z->parent; + z->parent = y; + z->right = y->left; + y->left = z; + if (z->right) { + z->right->meta &= ~IS_LEFT; + z->right->parent = z; + } + // === + node = parent->right; + } + if (node->right && !(node->right->meta & IS_BLACK)) { + case4_l: { + rbnode *y, *z; + y = node; + z = parent; + // ((Bchild), ?z, ((?y->left), By, (Ry->right))) + // y = BLACK, rchild of z + // z = ?, child of z->parent OR ROOT + // target = (((Bchild), Bz, (?y->left)), ?y, (By->right)) + if (z->parent) { + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + } + y->meta = z->meta; // same color as z + same side as z + z->meta = IS_BLACK | IS_LEFT; // black + left + y->parent = z->parent; + z->parent = y; + z->right = y->left; + y->left = z; + if (z->right) { + z->right->meta &= ~IS_LEFT; + z->right->parent = z; + } + if (!y->parent) tree->root = y; + node->right->meta |= IS_BLACK; + tree->is_unstable = 0; + return 0; } + } else if (!node->left || (node->left->meta & IS_BLACK)) { + // case2_l: + child = parent; // Remember that child can be NULL + parent = child->parent; + node->meta &= ~IS_BLACK; + } else { + // case3_l: + rbnode *y, *z; + y = node->left; + z = node; + // (((y->left), Ry, (y->right)), Bz, (Bz->right)) + // y = RED, rchild of z + // z = BLACK, child of z->parent + // target = ((y->left), By, ((y->right), Rz, (z->right))) + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + y->meta = z->meta; // black + same side as z + z->meta = 0; // red + right + y->parent = z->parent; + z->parent = y; + z->left = y->right; + y->right = z; + if (z->left) { + z->left->meta |= IS_LEFT; + z->left->parent = z; + } + node = y; + goto case4_l; + } + } else { + node = parent->left; + if (!(node->meta & IS_BLACK)) { + // rotate === + rbnode *y, *z; + y = node; + z = parent; + // (((y->left), Ry, (y->right)), Bz, (Bchild)) + // y = RED, lchild of z + // z = BLACK, child of z->parent OR ROOT + // target = ((y->left), By, ((y->right), Rz, (Bchild))) + if (z->parent) { + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + } + y->meta = z->meta; // black + same side as z + z->meta = 0; // red + right + y->parent = z->parent; + z->parent = y; + z->left = y->right; + y->right = z; + if (z->left) { + z->left->meta |= IS_LEFT; + z->left->parent = z; + } + if (!y->parent) tree->root = y; + // === + node = parent->left; + } + if (node->left && !(node->left->meta & IS_BLACK)) { + case4_r: { + rbnode *y, *z; + y = node; + z = y->parent; + // (((?y->left), By, (Ry->right)), ?z, (Bchild)) + // y = BLACK, rchild of z + // z = ?, child of z->parent OR ROOT + // target = ((?y->left), ?y, ((Ry->right), Bz, (Bchild))) + if (z->parent) { + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + } + y->meta = z->meta; // same color as z + same side as z + z->meta = IS_BLACK; // black + right + y->parent = z->parent; + z->parent = y; + z->left = y->right; + y->right = z; + if (z->left) { + z->left->meta |= IS_LEFT; + z->left->parent = z; + } + if (!y->parent) tree->root = y; + node->left->meta |= IS_BLACK; + tree->is_unstable = 0; + return 0; } + } else if (!node->right || (node->right->meta & IS_BLACK)) { + // case2_r: + child = parent; + parent = child->parent; + node->meta &= ~IS_BLACK; + } else { + // case3_r: + rbnode *y, *z; + y = node->right; + z = node; + // ((Bz->left), Bz, ((y->left), Ry, (y->right))) + // y = RED, rchild of z + // z = BLACK, child of z->parent + // target = (((Bz->left), Rz, (y->left)), By, (y->right)) + if (z->meta & IS_LEFT) { + z->parent->left = y; + } else { + z->parent->right = y; + } + y->meta = z->meta; // black + same side as z + z->meta = IS_LEFT; // red + left + y->parent = z->parent; + z->parent = y; + z->right = y->left; + y->left = z; + if (z->right) { + z->right->meta &= ~IS_LEFT; + z->right->parent = z; + } + node = y; + goto case4_r; + } + } + } + if (child) + child->meta |= IS_BLACK; + tree->is_unstable = 0; + return 0; +} + +rbnode *first_node(rbtree *tree) { + rbnode *node = tree->root, *prev = node; + while (node) { + prev = node; + node = node->left; + } + return prev; +} +rbnode *pred_node(rbnode *node) { + if (!node) return NULL; + if (node->left) { + node = node->left; + while (node->right) node = node->right; + return node; + } else { + while (node->parent && node->meta & IS_LEFT) node = node->parent; + return node->parent; + } +} +rbnode *succ_node(rbnode *node) { + if (!node) return NULL; + if (node->right) { + node = node->right; + while (node->left) node = node->left; + return node; + } else { + while (node->parent && !(node->meta & IS_LEFT)) node = node->parent; + return node->parent; + } +} + +uint8_t rb_get(rbtree *tree, uintptr_t addr) { + rbnode *node = find_addr(tree, addr); + if (node) return node->data; + else return 0; +} + +int rb_get_end(rbtree* tree, uintptr_t addr, uint8_t* val, uintptr_t* end) { + rbnode *node = tree->root, *next = NULL; + while (node) { + if (node->end <= addr) { + node = node->right; + } else if (node->start <= addr) { + *val = node->data; + *end = node->end; + return 1; + } else { + next = node; + node = node->left; + } + } + if (next) { + *val = next->data; + *end = next->start; + } else { + *val = 0; + *end = (uintptr_t)-1; + } + return 0; +} + +int rb_set(rbtree *tree, uintptr_t start, uintptr_t end, uint8_t data) { +// printf("rb_set( "); print_rbtree(tree); printf(" , 0x%lX, 0x%lX, %hhu);\n", start, end, data); fflush(stdout); +// dynarec_log(LOG_DEBUG, "set 0x%lX, 0x%lX, %hhu\n", start, end, data); + if (!tree->root) { + return add_range(tree, start, end, data); + } + + rbnode *node = tree->root, *prev = NULL, *last = NULL; + while (node) { + if (node->start < start) { + prev = node; + node = node->right; + } else if (node->start == start) { + if (node->left) { + prev = node->left; + while (prev->right) prev = prev->right; + } + if (node->right) { + last = node->right; + while (last->left) last = last->left; + } + break; + } else { + last = node; + node = node->left; + } + } + + // prev is the largest node starting strictly before start, or NULL if there is none + // node is the node starting exactly at start, or NULL if there is none + // last is the smallest node starting strictly after start, or NULL if there is none + // Note that prev may contain start + + if (prev && (prev->end >= start) && (prev->data == data)) { + // Merge with prev + if (end <= prev->end) return 0; // Nothing to do! + + if (node && (node->end > end)) { + node->start = end; + prev->end = end; + return 0; + } else if (node && (node->end == end)) { + remove_node(tree, node); + prev->end = end; + return 0; + } else if (node) { + remove_node(tree, node); + } + while (last && (last->start < end) && (last->end <= end)) { + // Remove the entire node + node = last; + last = succ_node(last); + remove_node(tree, node); + } + if (last && (last->start <= end) && (last->data == data)) { + // Merge node and last + prev->end = last->end; + remove_node(tree, last); + return 0; + } + if (last && (last->start < end)) last->start = end; + prev->end = end; + return 0; + } else if (prev && (prev->end > start)) { + if (prev->end > end) { + // Split in three + // Note that here, succ(prev) = last and node = NULL + int ret; + ret = add_range_next_to(tree, prev->right ? last : prev, end, prev->end, prev->data); + ret = ret ? ret : add_range_next_to(tree, prev->right ? succ_node(prev) : prev, start, end, data); + prev->end = start; + return ret; + } + // Cut prev and continue + prev->end = start; + } + + if (node) { + // Change node + if (node->end >= end) { + if (node->data == data) return 0; // Nothing to do! + // Cut node + if (node->end > end) { + int ret = add_range_next_to(tree, node->right ? last : node, end, node->end, node->data); + node->end = end; + node->data = data; + return ret; + } + // Fallthrough + } + + // Overwrite and extend node + while (last && (last->start < end) && (last->end <= end)) { + // Remove the entire node + prev = last; + last = succ_node(last); + remove_node(tree, prev); + } + if (last && (last->start <= end) && (last->data == data)) { + // Merge node and last + remove_node(tree, node); + last->start = start; + return 0; + } + if (last && (last->start < end)) last->start = end; + if (node->end < end) node->end = end; + node->data = data; + return 0; + } + + while (last && (last->start < end) && (last->end <= end)) { + // Remove the entire node + node = last; + last = succ_node(last); + remove_node(tree, node); + } + if (!last) { + // Add a new node next to prev, the largest node of the tree + // It exists since the tree is nonempty + return add_range_next_to(tree, prev, start, end, data); + } + if ((last->start <= end) && (last->data == data)) { + // Extend + last->start = start; + return 0; + } else if (last->start < end) { + // Cut + last->start = end; + } + // Probably 'last->left ? prev : last' is enough + return add_range_next_to(tree, last->left ? pred_node(last) : last, start, end, data); +} + +int rb_unset(rbtree *tree, uintptr_t start, uintptr_t end) { +// printf("rb_unset( "); print_rbtree(tree); printf(" , 0x%lX, 0x%lX);\n", start, end); fflush(stdout); +// dynarec_log(LOG_DEBUG, "rb_unset(tree, 0x%lX, 0x%lX);\n", start, end); + if (!tree->root) return 0; + + rbnode *node = tree->root, *prev = NULL, *next = NULL; + while (node) { + if (node->start < start) { + prev = node; + node = node->right; + } else if (node->start == start) { + if (node->left) { + prev = node->left; + while (prev->right) prev = prev->right; + } + if (node->right) { + next = node->right; + while (next->left) next = next->left; + } + break; + } else { + next = node; + node = node->left; + } + } + + if (node) { + if (node->end > end) { + node->start = end; + return 0; + } else if (node->end == end) { + remove_node(tree, node); + return 0; + } else { + remove_node(tree, node); + } + } else if (prev && (prev->end > start)) { + if (prev->end > end) { + // Split prev + int ret = add_range_next_to(tree, prev->right ? next : prev, end, prev->end, prev->data); + prev->end = start; + return ret; + } else if (prev->end == end) { + prev->end = start; + return 0; + } // else fallthrough + } + while (next && (next->start < end) && (next->end <= end)) { + // Remove the entire node + node = next; + next = succ_node(next); + remove_node(tree, node); + } + if (next && (next->start < end)) { + // next->end > end: cut the node + next->start = end; + } + return 0; +} + +#include <stdio.h> +void print_rbnode(const rbnode *node, unsigned depth, uintptr_t minstart, uintptr_t maxend, unsigned *bdepth) { + if (!node) { + if (!*bdepth || *bdepth == depth + 1) { + *bdepth = depth + 1; + printf("[%u]", depth); + } else + printf("<invalid black depth %u>", depth); + return; + } + if (node->start < minstart) { + printf("<invalid start>"); + return; + } + if (node->end > maxend) { + printf("<invalid end>"); + return; + } + printf("("); + if (node->left && !(node->left->meta & IS_LEFT)) { + printf("<invalid meta>"); + } else if (node->left && (node->left->parent != node)) { + printf("<invalid parent %p instead of %p>", node->left->parent, node); + } else if (node->left && !(node->meta & IS_BLACK) && !(node->left->meta & IS_BLACK)) { + printf("<invalid red-red node> "); + print_rbnode(node->left, depth + ((node->meta & IS_BLACK) ? 1 : 0), minstart, node->start, bdepth); + } else { + print_rbnode(node->left, depth + ((node->meta & IS_BLACK) ? 1 : 0), minstart, node->start, bdepth); + } + printf(", (%c/%p) %lX-%lX: %hhu, ", node->meta & IS_BLACK ? 'B' : 'R', node, node->start, node->end, node->data); + if (node->right && (node->right->meta & IS_LEFT)) { + printf("<invalid meta>"); + } else if (node->right && (node->right->parent != node)) { + printf("<invalid parent %p instead of %p>", node->right->parent, node); + } else if (node->right && !(node->meta & IS_BLACK) && !(node->right->meta & IS_BLACK)) { + printf("<invalid red-red node> "); + print_rbnode(node->right, depth + ((node->meta & IS_BLACK) ? 1 : 0), node->end, maxend, bdepth); + } else { + print_rbnode(node->right, depth + ((node->meta & IS_BLACK) ? 1 : 0), node->end, maxend, bdepth); + } + printf(")"); +} +void print_rbtree(const rbtree *tree) { + if (!tree) { + printf("<NULL>\n"); + return; + } + if (tree->root && tree->root->parent) { + printf("Root has parent\n"); + return; + } + if (tree->root && !(tree->root->meta & IS_BLACK)) { + printf("Root is red\n"); + return; + } + unsigned bdepth = 0; + print_rbnode(tree->root, 0, 0, (uintptr_t)-1, &bdepth); + printf("\n"); +} + +#ifdef RBTREE_TEST +int main() { + rbtree* tree = init_rbtree(); + print_rbtree(tree); fflush(stdout); + /*int ret; + ret = rb_set(tree, 0x43, 0x44, 0x01); + printf("%d; ", ret); print_rbtree(tree); fflush(stdout); + ret = rb_set(tree, 0x42, 0x43, 0x01); + printf("%d; ", ret); print_rbtree(tree); fflush(stdout); + ret = rb_set(tree, 0x41, 0x42, 0x01); + printf("%d; ", ret); print_rbtree(tree); fflush(stdout); + ret = rb_set(tree, 0x40, 0x41, 0x01); + printf("%d; ", ret); print_rbtree(tree); fflush(stdout); + ret = rb_set(tree, 0x20, 0x40, 0x03); + printf("%d; ", ret); print_rbtree(tree); fflush(stdout); + ret = rb_set(tree, 0x10, 0x20, 0x01); + printf("%d; ", ret); print_rbtree(tree); fflush(stdout); + + uint8_t val = rb_get(tree, 0x33); + printf("0x33 has attribute %hhu\n", val); fflush(stdout);*/ + /* rbnode *node = find_addr(tree, 0x33); + printf("0x33 is at %p: ", node); print_rbnode(node, 0); printf("\n"); fflush(stdout); + ret = remove_node(tree, node); + printf("%d; ", ret); print_rbtree(tree); fflush(stdout); + node = find_addr(tree, 0x20); + printf("0x20 is at %p\n", node); + node = find_addr(tree, 0x1F); + printf("0x1F is at %p: ", node); print_rbnode(node, 0); printf("\n"); fflush(stdout); + ret = remove_node(tree, node); + printf("%d; ", ret); print_rbtree(tree); fflush(stdout); */ + /* ret = rb_set(tree, 0x15, 0x42, 0x00); + printf("%d; ", ret); print_rbtree(tree); fflush(stdout); */ + /*rb_unset(tree, 0x15, 0x42); + print_rbtree(tree); fflush(stdout);*/ + + // tree->root = node27; print_rbtree(tree); fflush(stdout); + // rb_set(tree, 2, 3, 1); print_rbtree(tree); fflush(stdout); + // add_range_next_to(tree, node24, 0x0E7000, 0x0E8000, 69); print_rbtree(tree); fflush(stdout); + // print_rbtree(tree); fflush(stdout); + // uint8_t val = rb_get(tree, 0x11003000); + // printf("0x11003000 has attribute %hhu\n", val); fflush(stdout); + // remove_node(tree, node0); print_rbtree(tree); fflush(stdout); + // add_range_next_to(tree, node1, 0x0E7000, 0x0E8000, 69); print_rbtree(tree); fflush(stdout); +rb_set(tree, 0x130000, 0x140000, 7); + print_rbtree(tree); fflush(stdout); +rb_set(tree, 0x141000, 0x142000, 135); + print_rbtree(tree); fflush(stdout); +rb_set(tree, 0x140000, 0x141000, 135); + print_rbtree(tree); fflush(stdout); +rb_set(tree, 0x140000, 0x141000, 7); + print_rbtree(tree); fflush(stdout); +rb_set(tree, 0x140000, 0x141000, 135); + print_rbtree(tree); fflush(stdout); + uint8_t val = rb_get(tree, 0x141994); printf("0x141994 has attribute %hhu\n", val); fflush(stdout); + delete_rbtree(tree); +} +#endif diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index 13e50b09..53c426ff 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -148,8 +148,8 @@ ENTRYBOOL(BOX64_DYNAREC_CALLRET, box64_dynarec_callret) \ ENTRYBOOL(BOX64_DYNAREC_BLEEDING_EDGE, box64_dynarec_bleeding_edge) \ ENTRYBOOL(BOX64_DYNAREC_JVM, box64_dynarec_jvm) \ ENTRYBOOL(BOX64_DYNAREC_TBB, box64_dynarec_tbb) \ -ENTRYINT(BOX64_DYNAREC_HOTPAGE, box64_dynarec_hotpage, 0, 255, 8) \ -ENTRYBOOL(BOX64_DYNAREC_FASTPAGE, box64_dynarec_fastpage) \ +IGNORE(BOX64_DYNAREC_HOTPAGE) \ +IGNORE(BOX64_DYNAREC_FASTPAGE) \ ENTRYBOOL(BOX64_DYNAREC_ALIGNED_ATOMICS, box64_dynarec_aligned_atomics) \ ENTRYBOOL(BOX64_DYNAREC_WAIT, box64_dynarec_wait) \ ENTRYSTRING_(BOX64_NODYNAREC, box64_nodynarec) \ |