From 7db4e9cf35e3735cdeefaa167f6fc648c69b4580 Mon Sep 17 00:00:00 2001 From: HyperAssembler Date: Sat, 21 Mar 2015 14:17:38 -0700 Subject: [PATCH] Changed the interface for linked list and avl tree to a much more flexible one. The previous one was utter crap.. --- Test/avl_tree_test.c | 84 ++++++++ Test/linked_list_test.c | 99 --------- x64/src/c/avl_tree.c | 434 ++++++++++++++++++++++++---------------- x64/src/c/avl_tree.h | 40 ++-- x64/src/c/entry.c | 19 +- x64/src/c/int.c | 1 - x64/src/c/int.h | 3 - x64/src/c/linked_list.c | 265 +++++++++++------------- x64/src/c/linked_list.h | 30 ++- x64/src/c/mm.h | 8 + 10 files changed, 524 insertions(+), 459 deletions(-) create mode 100644 Test/avl_tree_test.c delete mode 100644 Test/linked_list_test.c delete mode 100644 x64/src/c/int.c delete mode 100644 x64/src/c/int.h diff --git a/Test/avl_tree_test.c b/Test/avl_tree_test.c new file mode 100644 index 0000000..8c57201 --- /dev/null +++ b/Test/avl_tree_test.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include "avl_tree.h" +typedef struct __attribute__ ((packed)) +{ + avl_tree_node node; + int val; +} int_node; + +int compare(void* a, void* b) +{ + int_node* aa = (int_node*)a; + int_node* bb = (int_node*)b; + if(aa->val > bb->val) + return 1; + else if(aa->val < bb->val) + return -1; + return 0; +} + +void in_order_print(avl_tree_node *tree) +{ + if (tree == NULL) + return; + avl_tree_node* node = avl_tree_node_largest(tree); + while(node != NULL) + { + printf("%d ", ((int_node*)node)->val); + node = avl_tree_node_prev(node); + } + return; +} + +int_node* create_int_node(int val) +{ + int_node* node = (int_node*)malloc(sizeof(int_node)); + avl_tree_node_init(&node->node); + node->val = val; + return node; +} + +int main (void) +{ + int_node* val[1000]; + srand((unsigned int)time(NULL)); + avl_tree* avlTree = (avl_tree*)malloc(sizeof(avl_tree)); + avl_tree_init(avlTree); + //test INSERT general + int i = 0; + for(i = 0; i < 1000; i++) + { + val[i] = create_int_node(rand()%10000); + avl_tree_insert(avlTree,(avl_tree_node*)val[i],compare); + assert(avl_tree_node_test(avlTree->root,compare)); + } + //test Delete general + for(i = 0; i < 1000; i++) + { + avl_tree_delete(avlTree,val[i],compare); + assert(avl_tree_node_test(avlTree->root,compare)); + free(val[i]); + } + + //test delete visualized + for(i = 0; i < 20; i++) + { + val[i] = create_int_node(rand()%2000); + avl_tree_insert(avlTree,(avl_tree_node*)val[i],compare); + assert(avl_tree_node_test(avlTree->root,compare)); + } + in_order_print(avlTree->root); + for(i = 0; i < 20; i++) + { + avl_tree_delete(avlTree,(avl_tree_node*)val[i],compare); + printf("\nDeleting: %d\n",val[i]->val); + in_order_print(avlTree->root); + assert(avl_tree_node_test(avlTree->root,compare)); + free(val[i]); + } + free(avlTree); + return 0; +} \ No newline at end of file diff --git a/Test/linked_list_test.c b/Test/linked_list_test.c deleted file mode 100644 index 8932b34..0000000 --- a/Test/linked_list_test.c +++ /dev/null @@ -1,99 +0,0 @@ -#include -#include -#include "linked_list.h" - -void print_list(linked_list* list) -{ - linked_list_iterator* it = linked_list_create_iterator(list); - it->current = list->tail; - while(it->current) - { - printf("%lu ", (unsigned long)it->current->data); - linked_list_prev(it); - } - printf("\n"); -} - -void insert_test(void) -{ - printf("insert test\n"); - linked_list* list; - //empty list at test - list = linked_list_create(); - linked_list_insert_at(list,0,(void*)2); - assert(list->size == 1 && list->head == list->tail && (int)list->head->data == 2); - print_list(list); - - //tail test - linked_list_insert_at(list,1,(void*)3); - assert(list->size == 2 && (int)list->tail->data == 3); - print_list(list); - - //head test - linked_list_insert_at(list,0,(void*)1); - assert(list->size == 3 && (int)list->head->data == 1); - print_list(list); - - //invalid index test - linked_list_insert_at(list,4,(void*)1); - assert(list->size == 3 && (int)list->head->data == 1 && (int)list->tail->data == 3); - print_list(list); - - //normal test - linked_list_insert_at(list,1,(void*)5); - assert(list->size == 4 && (int)list->head->next->data == 5 && (int)list->head->next->next->data == 2); - print_list(list); - - linked_list_free(list,NULL); - - return; -} - -void delete_test(void) -{ - printf("delete test\n"); - linked_list* list; - //empty list at test - list = linked_list_create(); - linked_list_insert(list,(void*)1); - linked_list_insert(list,(void*)2); - linked_list_insert(list,(void*)3); - linked_list_insert(list,(void*)4); - linked_list_insert(list,(void*)5); - - //head test - linked_list_delete_at(list,0); - assert(list->size == 4 && (int)list->head->data == 2); - print_list(list); - - //tail test - linked_list_delete_at(list,list->size-1); - assert(list->size == 3 && (int)list->tail->data == 4); - print_list(list); - - //normal test - linked_list_delete_at(list,1); - assert(list->size == 2 && (int)list->head->data == 2 && (int)list->head->next->data==4); - print_list(list); - - //invalid index test - linked_list_delete_at(list,2); - assert(list->size == 2 && (int)list->head->data == 2 && (int)list->head->next->data==4); - print_list(list); - - //delete last test - linked_list_delete_at(list,0); - linked_list_delete_at(list,0); - assert(list->size == 0 && list->head == NULL && list->tail == NULL); - - linked_list_free(list,NULL); - - return; -} - -int main(void) -{ - insert_test(); - delete_test(); - return 0; -} \ No newline at end of file diff --git a/x64/src/c/avl_tree.c b/x64/src/c/avl_tree.c index 8db941b..a4e8588 100644 --- a/x64/src/c/avl_tree.c +++ b/x64/src/c/avl_tree.c @@ -1,23 +1,21 @@ #include "kdef.h" -#include "mm.h" #include "avl_tree.h" #define MAX(a, b) (((a) > (b) ? (a) : (b))) -// internal -int NATIVE64 _avl_tree_get_height(avl_tree_node *node) +int NATIVE64 _avl_tree_node_get_height(avl_tree_node *node) { return node == NULL ? -1 : node->height; } -int NATIVE64 _avl_tree_get_balance_factor(avl_tree_node *node) +int NATIVE64 _avl_tree_node_get_balance_factor(avl_tree_node *node) { if (node == NULL) return 0; - return _avl_tree_get_height(node->left) - _avl_tree_get_height(node->right); + return _avl_tree_node_get_height(node->left) - _avl_tree_node_get_height(node->right); } -avl_tree_node * NATIVE64 _avl_tree_right_rotate(avl_tree_node *root) +avl_tree_node * NATIVE64 _avl_tree_node_right_rotate(avl_tree_node *root) { avl_tree_node *left_children = root->left; //adjust parents first @@ -29,12 +27,12 @@ avl_tree_node * NATIVE64 _avl_tree_right_rotate(avl_tree_node *root) root->left = root->left->right; left_children->right = root; //adjust height - root->height = MAX(_avl_tree_get_height(root->left), _avl_tree_get_height(root->right)) + 1; - left_children->height = MAX(_avl_tree_get_height(left_children->left), _avl_tree_get_height(left_children->right)) + 1; + root->height = MAX(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1; + left_children->height = MAX(_avl_tree_node_get_height(left_children->left), _avl_tree_node_get_height(left_children->right)) + 1; return left_children; } -avl_tree_node * NATIVE64 _avl_tree_left_rotate(avl_tree_node *root) +avl_tree_node * NATIVE64 _avl_tree_node_left_rotate(avl_tree_node *root) { avl_tree_node *right_children = root->right; //adjust parents @@ -46,41 +44,41 @@ avl_tree_node * NATIVE64 _avl_tree_left_rotate(avl_tree_node *root) root->right = root->right->left; right_children->left = root; - root->height = MAX(_avl_tree_get_height(root->left), _avl_tree_get_height(root->right)) + 1; - right_children->height = MAX(_avl_tree_get_height(right_children->left), _avl_tree_get_height(right_children->right)) + 1; + root->height = MAX(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1; + right_children->height = MAX(_avl_tree_node_get_height(right_children->left), _avl_tree_node_get_height(right_children->right)) + 1; return right_children; } -avl_tree_node * NATIVE64 _avl_tree_balance_node(avl_tree_node *node) +avl_tree_node * NATIVE64 _avl_tree_node_balance(avl_tree_node *node) { - const int bf = _avl_tree_get_balance_factor(node); + const int bf = _avl_tree_node_get_balance_factor(node); if (bf > 1) { - const int left_bf = _avl_tree_get_balance_factor(node->left); + const int left_bf = _avl_tree_node_get_balance_factor(node->left); if (left_bf >= 0) //left left - return _avl_tree_right_rotate(node); + return _avl_tree_node_right_rotate(node); else { //left right - node->left = _avl_tree_left_rotate(node->left); - return _avl_tree_right_rotate(node); + node->left = _avl_tree_node_left_rotate(node->left); + return _avl_tree_node_right_rotate(node); } } else if (bf < -1) { - const int right_bf = _avl_tree_get_balance_factor(node->right); + const int right_bf = _avl_tree_node_get_balance_factor(node->right); if (right_bf <= 0) { // right right - return _avl_tree_left_rotate(node); + return _avl_tree_node_left_rotate(node); } else { // right left - node->right = _avl_tree_right_rotate(node->right); - return _avl_tree_left_rotate(node); + node->right = _avl_tree_node_right_rotate(node->right); + return _avl_tree_node_left_rotate(node); } } else @@ -88,87 +86,166 @@ avl_tree_node * NATIVE64 _avl_tree_balance_node(avl_tree_node *node) } - -void * NATIVE64 _avl_tree_search(avl_tree_node *root, void *data, int(*compare)(void *, void *)) +avl_tree_node * NATIVE64 _avl_tree_node_insert(avl_tree_node *root, avl_tree_node *node, int(*compare)(void *, void *), avl_tree_node *parent) { - if(root == NULL) - return NULL; - const int comp = compare(root->data, data); - if (comp < 0) - return _avl_tree_search(root->right, data, compare); - else if (comp == 0) - return root->data; - else - return _avl_tree_search(root->left, data, compare); -} - -void * NATIVE64 avl_tree_search(avl_tree *root, void *data, int(*compare)(void *, void *)) -{ - if(root == NULL || data == NULL) - return NULL; - return _avl_tree_search(root->root, data, compare); -} - -avl_tree_node * NATIVE64 _avl_tree_create_node() -{ - avl_tree_node *tree = (avl_tree_node *) (kmalloc(sizeof(avl_tree_node))); - tree->parent = NULL; - tree->data = NULL; - tree->right = NULL; - tree->left = NULL; - tree->height = 0; - return tree; -} - -avl_tree_node * NATIVE64 _avl_tree_insert(avl_tree_node *root, void *data, int(*compare)(void *, void *), avl_tree_node *parent) -{ - if (data == NULL) + if (node == NULL) return root; if (root == NULL) { - avl_tree_node *tree = _avl_tree_create_node(); - tree->data = data; - tree->parent = parent; - return tree; + node->parent = parent; + return node; } - const int comp = compare(root->data, data); + const int comp = compare(root, node); if (comp < 0) - { - root->right = _avl_tree_insert(root->right, data, compare, root); - } + root->right = _avl_tree_node_insert(root->right, node, compare, root); else if (comp == 0) return root; else - root->left = _avl_tree_insert(root->left, data, compare, root); + root->left = _avl_tree_node_insert(root->left, node, compare, root); - root->height = MAX(_avl_tree_get_height(root->left), _avl_tree_get_height(root->right)) + 1; + root->height = MAX(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1; - return _avl_tree_balance_node(root); + return _avl_tree_node_balance(root); } -void NATIVE64 avl_tree_insert(avl_tree *tree, void *data, int (*compare)(void *, void *)) +void _swap_nodes(avl_tree_node *node1, avl_tree_node *node2) { - if(tree != NULL && data != NULL && compare != NULL) + if (node1 == NULL || node2 == NULL) + return; + avl_tree_node *parent = NULL; + avl_tree_node *child = NULL; + avl_tree_node *temp = NULL; + //swap node but does not change anything else other than node1,node2 + if (node1->parent != NULL && node1->parent == node2) { - if(avl_tree_search(tree, data, compare) == NULL) + parent = node2; + child = node1; + } + else if (node2->parent != NULL && node2->parent == node1) + { + parent = node1; + child = node2; + } + + if (parent != NULL && child != NULL) + { + //connected case + if(parent->parent != NULL) { - tree->root = _avl_tree_insert(tree->root, data, compare, NULL); - tree->size++; + if(parent->parent->left == parent) + parent->parent->left = child; + else + parent->parent->right = child; + } + //update left/right for parent + if(parent->left != NULL && child != parent->left) + { + parent->left->parent = child; + } + if(parent->right != NULL && child != parent->right) + { + parent->right->parent = child; + } + //update left/right for children + if(child->left != NULL) + child->left->parent = parent; + if(child->right != NULL) + child->right->parent = parent; + + child->parent = parent->parent; + parent->parent = child; + if (child == parent->left) + { + // parent + // / \ + // children + parent->left = child->left; + child->left = parent; + + temp = parent->right; + parent->right = child->right; + child->right = temp; + } + else + { + // parent + // / \ + // children + parent->right = child->right; + child->right = parent; + + temp = parent->left; + parent->left = child->left; + child->left = temp; } } + else + { + //not connected case + //adjust all the nodes other than node1,node2 + if(node1->left != NULL) + node1->left->parent = node2; + if(node1->right != NULL) + node1->right->parent = node2; + + if(node2->left != NULL) + node2->left->parent = node1; + if(node2->right != NULL) + node2->right->parent = node1; + + if(node1->parent != NULL) + { + if(node1->parent->left == node1) + node1->parent->left = node2; + else + node1->parent->right = node2; + } + + if(node2->parent != NULL) + { + if(node2->parent->left == node2) + node2->parent->left = node1; + else + node2->parent->right = node1; + } + + //adjust node1,node2 + temp = node1->parent; + node1->parent = node2->parent; + node2->parent = temp; + + temp = node1->left; + node1->left = node2->left; + node2->left = temp; + + temp = node1->right; + node1->right = node2->right; + node2->right = temp; + } + + //swap height + int height = node1->height; + node1->height = node2->height; + node2->height = height; return; } -avl_tree_node * NATIVE64 _avl_tree_delete(avl_tree_node *root, void *data, int (*compare)(void *, void *)) +//Interface +avl_tree_node* NATIVE64 avl_tree_node_insert(avl_tree_node* root, avl_tree_node* node, int(*compare)(void*,void*)) { - if (root == NULL || data == NULL) + return _avl_tree_node_insert(root, node, compare, NULL); +} + +avl_tree_node* NATIVE64 avl_tree_node_delete(avl_tree_node* root, avl_tree_node* node, int (*compare)(void *, void *)) +{ + if (root == NULL || node == NULL) return root; - const int comp = compare(root->data, data); + const int comp = compare(root, node); if (comp < 0) - root->right = _avl_tree_delete(root->right, data, compare); + root->right = avl_tree_node_delete(root->right, node, compare); else if(comp > 0) - root->left = _avl_tree_delete(root->left, data, compare); + root->left = avl_tree_node_delete(root->left, node, compare); else { // node with only one child or no child @@ -178,89 +255,64 @@ avl_tree_node * NATIVE64 _avl_tree_delete(avl_tree_node *root, void *data, int ( if(child == NULL) { // 0 child - //free(root); root = NULL; } else // 1 child { - //copy content of temp to root except for the parent - root->left = child->left; - root->right = child->right; - root->data = child->data; - root->height = child->height; - //free(child); + child->parent = root->parent; + root = child; } } else { // node with two children: Get the inorder successor (smallest // in the right subtree) + avl_tree_node *successor = root->right; + while(successor->left != NULL) + successor = successor->left; + //swap fields + _swap_nodes(successor,root); - avl_tree_node * temp = root->right; - while(temp->left != NULL) - temp = temp->left; + // Detach the inorder successor + successor->right = avl_tree_node_delete(successor->right, root, compare); - // Copy the inorder successor's data to this node - root->data = temp->data; - - // Delete the inorder successor - root->right = _avl_tree_delete(root->right, temp->data, compare); + root = successor; } } if (root == NULL) return root; - root->height = MAX(_avl_tree_get_height(root->left), _avl_tree_get_height(root->right)) + 1; - root = _avl_tree_balance_node(root); + root->height = MAX(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1; + root = _avl_tree_node_balance(root); return root; } -void NATIVE64 avl_tree_delete(avl_tree *tree, void *data, int (*compare)(void *, void *)) +avl_tree_node* NATIVE64 avl_tree_node_search(avl_tree_node *root, avl_tree_node* node, int(*compare)(void *, void *)) { - if(tree != NULL && data != NULL && compare != NULL && tree->size != 0) + if(root == NULL) + return NULL; + const int comp = compare(root, node); + if (comp < 0) + return avl_tree_node_search(root->right, node, compare); + else if (comp == 0) + return root; + else + return avl_tree_node_search(root->left, node, compare); +} + +void NATIVE64 avl_tree_node_init(avl_tree_node* it) +{ + if(it != NULL) { - if(avl_tree_search(tree, data, compare) != NULL) - { - tree->root = _avl_tree_delete(tree->root, data, compare); - tree->size--; - } + it->height = 0; + it->left = NULL; + it->right = NULL; + it->parent = NULL; } return; } -void NATIVE64 _avl_tree_free(avl_tree_node *root, void (*delete_data)(void *)) -{ - if(root != NULL) - { - _avl_tree_free(root->left, delete_data); - _avl_tree_free(root->right, delete_data); - if (delete_data != NULL) - delete_data(root->data); - } - return; -} -void NATIVE64 avl_tree_free(avl_tree *tree, void (*delete_data)(void *)) -{ - if(tree != NULL) - { - _avl_tree_free(tree->root, delete_data); - kfree(tree); - } - return; -} - -avl_tree * NATIVE64 avl_tree_create() -{ - avl_tree* new_tree = kmalloc(sizeof(avl_tree)); - new_tree->root = NULL; - new_tree->size = 0; - return new_tree; -} - - -//iterator - -avl_tree_node * NATIVE64 _avl_tree_smallest(avl_tree_node *root) +avl_tree_node * NATIVE64 avl_tree_node_smallest(avl_tree_node *root) { if (root == NULL) return NULL; @@ -269,89 +321,135 @@ avl_tree_node * NATIVE64 _avl_tree_smallest(avl_tree_node *root) return root; } -avl_tree_iterator* NATIVE64 avl_tree_create_iterator(avl_tree *tree) +avl_tree_node * NATIVE64 avl_tree_node_largest(avl_tree_node *root) { - if(tree == NULL) + if (root == NULL) return NULL; - avl_tree_iterator* it = (avl_tree_iterator*)kmalloc(sizeof(avl_tree_iterator)); - it->current = _avl_tree_smallest(tree->root); - return it; + while (root->right != NULL) + root = root->right; + return root; } -void NATIVE64 avl_tree_next(avl_tree_iterator *it) + +avl_tree_node* NATIVE64 avl_tree_node_next(avl_tree_node *it) { - if (it == NULL || it->current == NULL) - return; - avl_tree_node* root = it->current; + if (it == NULL) + return NULL; + avl_tree_node* root = it; if (root->right != NULL) { root = root->right; while (root->left != NULL) - { root = root->left; - } - it->current = root; - return; + return root; } else { while (root->parent != NULL) { if (root->parent->left == root) - { - it->current = root->parent; - return; - } + return root->parent; root = root->parent; } - it->current = NULL; - return; + return NULL; } } -void NATIVE64 avl_tree_prev(avl_tree_iterator *it) +avl_tree_node* NATIVE64 avl_tree_node_prev(avl_tree_node *it) { - if (it == NULL || it->current == NULL) - return; - avl_tree_node* root = it->current; + if (it == NULL) + return NULL; + avl_tree_node* root = it; if (root->left != NULL) { root = root->left; while (root->right != NULL) - { root = root->right; - } - it->current = root; + return root; } else { while (root->parent != NULL) { if (root->parent->right == root) - { - it->current = root->parent; - } + return root->parent; root = root->parent; } - it->current = NULL; + return NULL; } } +avl_tree_node* avl_tree_search(avl_tree *tree, avl_tree_node* node, int (*compare)(void *, void *)) +{ + return avl_tree_node_search(tree->root,node,compare); +} + + +void NATIVE64 avl_tree_insert(avl_tree *tree, void *data, int (*compare)(void *, void *)) +{ + if(tree != NULL && data != NULL && compare != NULL) + { + if(avl_tree_search(tree, data, compare) == NULL) + { + tree->root = _avl_tree_node_insert(tree->root, data, compare, NULL); + tree->size++; + } + } + return; +} + +void NATIVE64 avl_tree_delete(avl_tree *tree, void *data, int (*compare)(void *, void *)) +{ + if(tree != NULL && data != NULL && compare != NULL && tree->size != 0) + { + if(avl_tree_search(tree, data, compare) != NULL) + { + tree->root = avl_tree_node_delete(tree->root, data, compare); + tree->size--; + } + } + return; +} + +void NATIVE64 avl_tree_init(avl_tree* tree) +{ + if(tree != NULL) + { + tree->root = NULL; + tree->size = 0; + } + return; +} // TESTS -int NATIVE64 avl_tree_test_calculate_height(avl_tree_node *tree) +int NATIVE64 avl_tree_node_calculate_height(avl_tree_node *tree) { if (tree == NULL) return -1; - return MAX(avl_tree_test_calculate_height(tree->left), avl_tree_test_calculate_height(tree->right)) + 1; + return MAX(avl_tree_node_calculate_height(tree->left), avl_tree_node_calculate_height(tree->right)) + 1; } -int NATIVE64 avl_tree_test(avl_tree_node *tree) +int NATIVE64 avl_tree_node_test(avl_tree_node *tree, int (*compare)(void*,void*)) { if (tree == NULL) return 1; - if (_avl_tree_get_balance_factor(tree) < -1 || _avl_tree_get_balance_factor(tree) > 1 || avl_tree_test_calculate_height(tree) != tree->height) + if (_avl_tree_node_get_balance_factor(tree) < -1 || _avl_tree_node_get_balance_factor(tree) > 1 || avl_tree_node_calculate_height(tree) != tree->height) return 0; - return avl_tree_test(tree->left) && avl_tree_test(tree->right); + if(tree->left != NULL) + { + if(tree->left->parent != tree) + return 0; + } + if(tree->right != NULL) + { + if(tree->right->parent != tree) + return 0; + } + if(compare != NULL) + { + if((tree->right != NULL && compare(tree,tree->right) > 0) || (tree->left != NULL && compare(tree,tree->left) < 0)) + return 0; + } + return avl_tree_node_test(tree->left,compare) && avl_tree_node_test(tree->right,compare); } diff --git a/x64/src/c/avl_tree.h b/x64/src/c/avl_tree.h index ebf846b..ea7c7ae 100644 --- a/x64/src/c/avl_tree.h +++ b/x64/src/c/avl_tree.h @@ -8,7 +8,6 @@ typedef struct __attribute__((packed)) _avl_tree_node struct _avl_tree_node * right; struct _avl_tree_node * parent; int height; - void *data; } avl_tree_node; typedef struct __attribute__((packed)) @@ -17,29 +16,36 @@ typedef struct __attribute__((packed)) int size; } avl_tree; -typedef struct __attribute__((packed)) -{ - avl_tree_node * current; -} avl_tree_iterator; +avl_tree_node* NATIVE64 avl_tree_node_insert(avl_tree_node* root, avl_tree_node* node, int(*compare)(void*,void*)); + +avl_tree_node* NATIVE64 avl_tree_node_delete(avl_tree_node* root, avl_tree_node* node, int (*compare)(void *, void *)); + +avl_tree_node* NATIVE64 avl_tree_node_search(avl_tree_node *root, avl_tree_node* node, int(*compare)(void *, void *)); + +void NATIVE64 avl_tree_node_init(avl_tree_node* it); + +avl_tree_node* NATIVE64 avl_tree_node_next(avl_tree_node *it); + +avl_tree_node* NATIVE64 avl_tree_node_prev(avl_tree_node *it); + +avl_tree_node * NATIVE64 avl_tree_node_smallest(avl_tree_node *root); + +avl_tree_node * NATIVE64 avl_tree_node_largest(avl_tree_node *root); + + + +avl_tree_node* avl_tree_search(avl_tree *tree, avl_tree_node* node, int (*compare)(void *, void *)); void NATIVE64 avl_tree_insert(avl_tree *tree, void *data, int (*compare)(void *, void *)); void NATIVE64 avl_tree_delete(avl_tree *tree, void *data, int (*compare)(void *, void *)); -void NATIVE64 avl_tree_free(avl_tree *tree, void (*delete_data)(void *)); +void NATIVE64 avl_tree_init(avl_tree* tree); -void NATIVE64 *avl_tree_search(avl_tree *tree, void *data, int(*compare)(void *, void *)); +// TESTS -avl_tree * NATIVE64 avl_tree_create(); +int NATIVE64 avl_tree_node_calculate_height(avl_tree_node *tree); -avl_tree_iterator* NATIVE64 avl_tree_create_iterator(avl_tree *tree); - -void NATIVE64 avl_tree_next(avl_tree_iterator *it); - -void NATIVE64 avl_tree_prev(avl_tree_iterator *it); - -int NATIVE64 avl_tree_test_calculate_height(avl_tree_node *tree); - -int NATIVE64 avl_tree_test(avl_tree_node *tree); +int NATIVE64 avl_tree_node_test(avl_tree_node *tree, int(*compare)(void *, void *)); #endif \ No newline at end of file diff --git a/x64/src/c/entry.c b/x64/src/c/entry.c index d681511..b087dbb 100644 --- a/x64/src/c/entry.c +++ b/x64/src/c/entry.c @@ -3,6 +3,8 @@ #include "print.h" #include "mm.h" #include "multiboot.h" +#include "linked_list.h" + uint8_t g_gdt[8*9]; gdt_ptr_t g_gdt_ptr; extern uint64_t text_pos; @@ -26,12 +28,13 @@ void NATIVE64 kmain(multiboot_info_t *multiboot_info) write_segment_descriptor((void *) &g_gdt[48], 0, 0xFFFFF, SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_TYPE_DATA_RW); write_segment_descriptor((void *) &g_gdt[56], 0, 0xFFFFF, SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_TYPE_CODE_X); write_segment_descriptor((void *) &g_gdt[64], 0, 0xFFFFF, SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_TYPE_DATA_RW); - g_gdt_ptr.base = (uint64_t)g_gdt; g_gdt_ptr.limit = 8*9-1; flush_gdt(&g_gdt_ptr, SEG_SELECTOR(1, 0), SEG_SELECTOR(2, 0)); kprintf("Done.\n\n"); - + linked_list* mm_list = (linked_list*)kmalloc(sizeof(linked_list)); + linked_list_init(mm_list); + kprintf("allocated:0x%x\n",(uint64_t)mm_list); kprintf("*Checking memory information...\n"); if(multiboot_info->flags & (1 << 6)) { @@ -40,7 +43,7 @@ void NATIVE64 kmain(multiboot_info_t *multiboot_info) kprintf("BaseAddr - Length - Type\n"); uint64_t total_available_mem = 0; uint64_t total_reserved_mem = 0; - for (uint64_t i = 0; i < mem_map_size; i++) + for (int i = 0; i < mem_map_size; i++) { kprintf("0x%X - 0x%X - 0x%x\n", (mem_map + i)->addr, (mem_map + i)->len, (mem_map + i)->type); if((mem_map + i)->type == MULTIBOOT_MEMORY_RESERVED) @@ -49,11 +52,21 @@ void NATIVE64 kmain(multiboot_info_t *multiboot_info) } else if ((mem_map + i)->type == MULTIBOOT_MEMORY_AVAILABLE) { + phy_mem_info* mm_info = kmalloc(sizeof(phy_mem_info)); + linked_list_node_init(&mm_info->node); + mm_info->base = (mem_map+i)->addr; + mm_info->limit = (mem_map+i)->len; + linked_list_add(mm_list,(linked_list_node*)mm_info); total_available_mem += (mem_map + i)->len; } } kprintf("Total available memory: %uB, %uKB, %uMB.\n", total_available_mem, total_available_mem / 1024, total_available_mem / 1024 / 1024); kprintf("Total reserved memory: %uB, %uKB, %uMB.\n\n", total_reserved_mem, total_reserved_mem / 1024, total_reserved_mem / 1024 / 1024); + for(int i = 0; i < mm_list->size; i++) + { + phy_mem_info* mem_info = (phy_mem_info*)linked_list_get(mm_list,i); + kprintf("0x%X - 0x%X", mem_info->base, mem_info->limit); + } } else { diff --git a/x64/src/c/int.c b/x64/src/c/int.c deleted file mode 100644 index e990c87..0000000 --- a/x64/src/c/int.c +++ /dev/null @@ -1 +0,0 @@ -#include "int.h" \ No newline at end of file diff --git a/x64/src/c/int.h b/x64/src/c/int.h deleted file mode 100644 index b8f3f08..0000000 --- a/x64/src/c/int.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef _INT_H_ -#define _INT_H_ -#endif diff --git a/x64/src/c/linked_list.c b/x64/src/c/linked_list.c index aa7eae9..ebb2a6b 100644 --- a/x64/src/c/linked_list.c +++ b/x64/src/c/linked_list.c @@ -1,193 +1,156 @@ -#include "mm.h" +#include "kdef.h" #include "linked_list.h" -//internal - -linked_list_node* NATIVE64 _linked_list_get_by_index(linked_list_node *head, int index) +void NATIVE64 linked_list_node_init(linked_list_node* node) { - while(1) + if(node != NULL) { - if(index <= 0 || head == NULL) - return head; - head = head->next; - index--; - } -} - -linked_list_node* NATIVE64 _linked_list_get_by_element(linked_list_node *head, void *data, int(*compare)(int *, int *)) -{ - while(1) - { - if(head == NULL || compare(data,head->data) == 0) - return head; - head = head->next; - } -} - - -linked_list_node* NATIVE64 _linked_list_create_node() -{ - linked_list_node* node = (linked_list_node*)kmalloc(sizeof(linked_list_node)); - node->data = NULL; - node->prev = NULL; - node->next = NULL; - return node; -} - -void NATIVE64 _linked_list_delete_node(linked_list *list, linked_list_node *node) -{ - if(list != NULL && node != NULL) - { - //check if itself is head - if(list->head == node) - { - list->head = node->next; - } - //check if itself is tail - if(list->tail == node) - { - list->tail = node->prev; - } - if (node->prev != NULL) - node->prev->next = node->next; - if (node->next != NULL) - node->next->prev = node->prev; - list->size--; - kfree(node); + node->prev = NULL; + node->next = NULL; } return; } -//interface -linked_list* NATIVE64 linked_list_create() +linked_list_node* NATIVE64 linked_list_node_get(linked_list_node * head, int index) { - linked_list* list = (linked_list*)kmalloc(sizeof(linked_list)); - list->size = 0; - list->tail = NULL; - list->head = NULL; - return list; + if(head == NULL || index < 0) + return NULL; + while(index--) + { + head = head->next; + if(head == NULL) + break; + } + return head; } -void NATIVE64 linked_list_free(linked_list* list, void(*delete_data)(void*)) +int NATIVE64 linked_list_node_size(linked_list_node* head) { - if(list == NULL) - return; - linked_list_node* head = list->head; + int i = 0; while(head != NULL) { - linked_list_node* temp = head; + i++; head = head->next; - if(delete_data != NULL) - delete_data(temp->data); - kfree(temp); } - kfree(list); - return; + return i; } -void NATIVE64 linked_list_insert(linked_list * list, void* data) +//returns new head +linked_list_node* NATIVE64 linked_list_node_insert(linked_list_node * head, int index, linked_list_node* node) { - if(list == NULL) - return; - linked_list_node* node = _linked_list_create_node(); - node->data = data; - if(list->tail != NULL) + if(head == NULL) + return node; + if(node == NULL || index < 0) + return head; + //@ head != NULL + if(index == 0) { - //already elements in the list - //guaranteed that list->next == NULL - node->prev = list->tail; - list->tail->next = node; - list->tail = node; + //insert at head + node->prev = NULL; + node->next = head; + head->prev = node; + return node; } else { - //no element case - list->tail = node; - list->head = node; + linked_list_node* target = linked_list_node_get(head, index-1); + if(target == NULL) + return NULL; + node->prev = target; + node->next = target->next; + if(target->next != NULL) + target->next->prev = node; + target->next = node; + return head; } - list->size++; +} + +void NATIVE64 linked_list_node_add(linked_list_node * head, linked_list_node* node) +{ + if(head == NULL || node == NULL) + return; + int size = linked_list_node_size(head); + linked_list_node_insert(head,size,node); return; } -void NATIVE64 linked_list_insert_at(linked_list * list, int position, void* data) +//returns new head +linked_list_node* NATIVE64 linked_list_node_remove(linked_list_node *head, int index) { - if(list != NULL && position >= 0 && position <= list->size) + if(head == NULL || index < 0) + return head; + if(index == 0) + { + linked_list_node* next = head->next; + head->next = NULL; + head->prev = NULL; + if(next != NULL) + next->prev = NULL; + return next; + } + else + { + linked_list_node *target = linked_list_node_get(head, index); + if (target->prev != NULL) + target->prev->next = target->next; + if (target->next != NULL) + target->next->prev = target->prev; + target->prev = NULL; + target->next = NULL; + return head; + } +} + + +void NATIVE64 linked_list_init(linked_list* list) +{ + if(list != NULL) + { + list->size = 0; + list->head = NULL; + } + return; +} + +void NATIVE64 linked_list_add(linked_list * list, linked_list_node* node) +{ + if(list != NULL && node != NULL) + { + //@ node != NULL + if (list->head == NULL) { - linked_list_node* target = _linked_list_get_by_index(list->head, position); - if(target == NULL) - { - //tail case - linked_list_insert(list, data); + list->head = node; } else - { - //head or normal case - linked_list_node* node = _linked_list_create_node(); - node->data = data; - if (list->head == target) { - list->head = node; - } - node->prev = target->prev; - node->next = target; - if (target->prev != NULL) - target->prev->next = node; - target->prev = node; - list->size++; - } + linked_list_node_add(list->head, node); + list->size++; } return; } -void* NATIVE64 linked_list_get(linked_list * list, int index) +void NATIVE64 linked_list_insert(linked_list * list, int index, linked_list_node* node) { - if(list == NULL || list->head == NULL || index < 0 || list->size <= index) + if(list != NULL && index > 0 && node != NULL) + { + list->head = linked_list_node_insert(list->head, index, node); + list->size++; + } + return; +} + +linked_list_node* NATIVE64 linked_list_get(linked_list * list, int index) +{ + if(list == NULL || index < 0 || index >= list->size) return NULL; - linked_list_node* node = _linked_list_get_by_index(list->head, index); - return node == NULL ? NULL : node->data; + return linked_list_node_get(list->head,index); } -void NATIVE64 linked_list_delete(linked_list * list, void* data, int(*compare)(int*,int*)) +void NATIVE64 linked_list_remove(linked_list *list, int index) { - if(list == NULL || list->head == NULL || compare == NULL) - return; - linked_list_node* node = _linked_list_get_by_element(list->head, data, compare); - _linked_list_delete_node(list, node); - return; -} - -void NATIVE64 linked_list_delete_at(linked_list * list, int index) -{ - if(list == NULL || list->head == NULL || index < 0 || list->size <= index) - return; - linked_list_node* node = _linked_list_get_by_index(list->head, index); - _linked_list_delete_node(list, node); - return; -} - -// iterator -linked_list_iterator* NATIVE64 linked_list_create_iterator(linked_list* list) -{ - if(list == NULL) - return NULL; - linked_list_iterator* it = (linked_list_iterator*)kmalloc(sizeof(linked_list_iterator)); - it->current = list->head; - return it; -} - -void NATIVE64 linked_list_delete_iterator(linked_list_iterator* it) -{ - kfree(it); - return; -} - -void NATIVE64 linked_list_prev(linked_list_iterator* it) -{ - it->current = it->current->prev; - return; -} - -void NATIVE64 linked_list_next(linked_list_iterator* it) -{ - it->current = it->current->next; + if(list != NULL && index >= 0 && index < list->size) + { + list->head = linked_list_node_remove(list->head, index); + list->size--; + } return; } \ No newline at end of file diff --git a/x64/src/c/linked_list.h b/x64/src/c/linked_list.h index ef35e94..94b0ffb 100644 --- a/x64/src/c/linked_list.h +++ b/x64/src/c/linked_list.h @@ -1,44 +1,40 @@ #ifndef _LINKED_LIST_H_ #define _LINKED_LIST_H_ +#include "kdef.h" typedef struct _linked_list_node { struct _linked_list_node* prev; struct _linked_list_node* next; - void* data; } linked_list_node; typedef struct { linked_list_node* head; - linked_list_node* tail; int size; } linked_list; -typedef struct -{ - linked_list_node* current; -} linked_list_iterator; +void NATIVE64 linked_list_init(linked_list* list); -linked_list* NATIVE64 linked_list_create(); +void NATIVE64 linked_list_add(linked_list * list, linked_list_node* node); -void NATIVE64 linked_list_insert(linked_list * list, void* data); +void NATIVE64 linked_list_insert(linked_list * list, int index, linked_list_node* node); -void NATIVE64 linked_list_insert_at(linked_list * list, int position, void* data); +linked_list_node* NATIVE64 linked_list_get(linked_list * list, int index); -void* NATIVE64 linked_list_get(linked_list * list, int index); +void NATIVE64 linked_list_remove(linked_list *list, int index); -void NATIVE64 linked_list_delete(linked_list * list, void* data, int(*compare)(int*,int*)); -void NATIVE64 linked_list_delete_at(linked_list * list, int index); -linked_list_iterator* NATIVE64 linked_list_create_iterator(linked_list* list); +int NATIVE64 linked_list_node_size(linked_list_node* head); -void NATIVE64 linked_list_delete_iterator(linked_list_iterator* it); +void NATIVE64 linked_list_node_init(linked_list_node* node); -void NATIVE64 linked_list_prev(linked_list_iterator* it); +void NATIVE64 linked_list_node_add(linked_list_node * head, linked_list_node* node); -void NATIVE64 linked_list_next(linked_list_iterator* it); +linked_list_node* NATIVE64 linked_list_node_insert(linked_list_node * head, int index, linked_list_node* node); -void NATIVE64 linked_list_free(linked_list* list, void(*delete_data)(void*)); +linked_list_node* NATIVE64 linked_list_node_get(linked_list_node * head, int index); + +linked_list_node* NATIVE64 linked_list_node_remove(linked_list_node *head, int index); #endif diff --git a/x64/src/c/mm.h b/x64/src/c/mm.h index 44bee70..6f0362b 100644 --- a/x64/src/c/mm.h +++ b/x64/src/c/mm.h @@ -3,6 +3,7 @@ #include "type.h" #include "kdef.h" +#include "linked_list.h" #define PML4_PRESENT (1ull << 0) #define PML4_WRITE (1ull << 1) #define PML4_USER (1ull << 2) @@ -68,6 +69,13 @@ typedef struct __attribute__ ((packed)) uint64_t base; } gdt_ptr_t; +typedef struct __attribute__ ((packed)) +{ + linked_list_node node; + uint64_t base; + uint64_t limit; +} phy_mem_info; + void*NATIVE64 kmalloc(size_t const size); void NATIVE64 kfree(void* ptr);