LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 12-01-2019, 04:43 AM   #1
godsfame
LQ Newbie
 
Registered: Dec 2019
Posts: 2

Rep: Reputation: Disabled
Linux Kernel freezing when inserting 384 elements into BST module


Hi guys,

I am completely stuck on this problem and my searches over the internet resulted in no progress so I am here.

I currently am running this on Ubuntu 18.03 with my kernel version being 5.2.11
I have no idea why this module freezes on 384 elements being inserted into the BST. I was wondering if any of you could help me on this or if this was the wrong place to post. Any tips/comments would be greatly appreciated


Code:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>

long long last_saved_time;

long long current_timestamp(void) {
	struct timespec ts;
	getnstimeofday(&ts); // get current time
	long long milliseconds = ts.tv_sec*1000LL + ts.tv_nsec/1000000; // calculate milliseconds
	return milliseconds;
}

/*
 * This structure represents a single node in a BST.
 */
struct bst_node {
	int val;
	struct bst_node* left;
	struct bst_node* right;
};

/*
 * This structure represents an entire BST.  Note that we only need a
 * reference to the root node of the tree.
 */
struct bst {
	struct bst_node* root;
};


struct bst* bst_create(void) {
	struct bst* bst = kmalloc(sizeof(struct bst), GFP_KERNEL);
	bst->root = NULL;
	return bst;
}


int bst_isempty(struct bst* bst) {
	return bst->root == NULL;
}

int _bst_subtree_min_val(struct bst_node* n) {
	/*
	 * The minimum value in any subtree is just the leftmost value.  Keep going
	 * left till we get there.
	 */
	while (n->left != NULL) {
		n = n->left;
	}
	return n->val;
}

/*
 * Helper function to remove a given value from a subtree of a BST rooted at
 * a specified node.  Operates recursively by figuring out whether val is in
 * the left or the right subtree of the specified node and performing the
 * remove operation on that subtree.
 *
 * Returns the potentially new root of the given subtree, modified to have
 * the specified value removed.
 */
struct bst_node* _bst_subtree_remove(int val, struct bst_node* n) {

	if (n == NULL) {

		/*
		 * If n is NULL, that means we've reached a leaf node without finding
		 * the value we wanted to remove.  The tree won't be modified.
		 */
		return NULL;

	} else if (val < n->val) {

		/*
		 * If val is less than n, remove val from n's left subtree and update
		 * n->left to point to the modified subtree (with val removed).  Return n,
		 * whose subtree itself has now been modified.
		 */
		n->left = _bst_subtree_remove(val, n->left);
		return n;

	} else if (val > n->val) {

		/*
		 * If val is greater than n, remove val from n's right subtree and update
		 * n->right to point to the modified subtree (with val removed).  Return n,
		 * whose subtree itself has now been modified.
		 */
		n->right = _bst_subtree_remove(val, n->right);
		return n;

	} else {

		/*
		 * If we've reached this point, we've found a node with value val.  We
		 * need to remove this node from the tree, and the way we do that will
		 * differ based on whether the node has 0, 1, or 2 children.
		 */
		if (n->left != NULL && n->right != NULL) {

			/*
			 * If n has 2 children, we replace the value at n with the value at n's
			 * in-order successor node, which is the minimum value in n's right
			 * subtree.  Then we recursively remove n's in-order successor node from
			 * the tree (specifically from n's right subtree).
			 */
			n->val = _bst_subtree_min_val(n->right);
			n->right = _bst_subtree_remove(n->val, n->right);
			return n;

		} else if (n->left != NULL) {

			/*
			 * If n has only a left child, we simply delete n by freeing it and
			 * returning the left child node so that it becomes the new child of
			 * n's parent via the recursion.
			 */
			struct bst_node* left_child = n->left;
			kfree(n);
			return left_child;

		} else if (n->right != NULL) {

			/*
			 * If n has only a right child, we simply delete n by freeing it and
			 * returning the right child node so that it becomes the new child of
			 * n's parent via the recursion.
			 */
			struct bst_node* right_child = n->right;
			kfree(n);
			return right_child;

		} else {

			/*
			 * Otherwise, n has no children, and we can simply free it and return
			 * NULL so that n's parent will lose n as a child via the recursion.
			 */
			kfree(n);
			return NULL;

		}

	}

}
void bst_remove(int val, struct bst* bst) {
	/*
	 * We remove val by using our subtree removal function starting with the
	 * subtree rooted at bst->root (i.e. the whole tree).
	 */
	bst->root = _bst_subtree_remove(val, bst->root);
}

void bst_free(struct bst* bst) {

	/*
	 * Assume that bst_remove() frees each node it removes and use it to free
	 * all of the nodes in the tree.
	 */
	while (!bst_isempty(bst)) {
		bst_remove(bst->root->val, bst);
	}
	kfree(bst);
	printk("BST IS FREE\n");
}


/*
 * Helper function to generate a single BST node containing a given value.
 */
struct bst_node* _bst_node_create(int val) {
	struct bst_node* n = kmalloc(sizeof(struct bst_node), GFP_KERNEL);
	n->val = val;
	n->left = n->right = NULL;
	return n;
}


/*
 * Helper function to insert a given value into a subtree of a BST rooted at
 * a given node.  Operates recursively by determining into which subtree (left
 * or right) under the given node the value should be inserted and performing
 * the insertion on that subtree.
 *
 * Returns the root of the given subtree, modified to contain a new node with
 * the specified value.
 */
struct bst_node* _bst_subtree_insert(int val, struct bst_node* n) {

	if (n == NULL) {

		/*
		 * If n is NULL, we know we've reached a place to insert val, so we
		 * create a new node holding val and return it.
		 */
		return _bst_node_create(val);

	} else if (val < n->val) {

		/*
		 * If val is less than the value at n, we insert val in n's left subtree
		 * (somewhere) and update n->left to point to the modified subtree (with
		 * val inserted).
		 */
		n->left = _bst_subtree_insert(val, n->left);

	} else {

		/*
		 * If val is greater than or equal to the value at n, we insert val in n's
		 * right subtree (somewhere) and update n->right to point to the modified
		 * subtree (with val inserted).
		 */
		n->right = _bst_subtree_insert(val, n->right);

	}

	/*
	 * For the else if and else conditions, the subtree rooted at n has already
	 * been modified (by setting n->left or n->right above), so we can just
	 * return n here.
	 */
	return n;

}


void bst_insert(int val, struct bst* bst) {
	/*
	 * We insert val by using our subtree insertion function starting with the
	 * subtree rooted at bst->root (i.e. the whole tree).
	 */
	bst->root = _bst_subtree_insert(val, bst->root);

}


void bst_search(int val, struct bst_node* node){
	if (!node)
		return 0;
	else if (val < node->val)
		bst_search(val, node->left);
	else if (val > node->val)
		bst_search(val, node->right);
	else
		return 0;
}

int bst_insert_search_delete(int n) {
	//	int num_of_elems[3] = {1000, 10000, 100000};
	int i;
	for (i=0; i < 1; i++){
		// initialize bst
		struct bst* bst = bst_create();

		// add items into bst
		last_saved_time = current_timestamp();
		int j;
		for (j=0; j < n; j++){
			bst_insert(j, bst);
		}
		printk("time in ms to insert %d elements: %lld\n", n, current_timestamp()-last_saved_time);

		// search items in bst
		last_saved_time = current_timestamp();
		int k;
		for (k=0; k < n; k++){
			bst_search(k, bst->root);
		}
		printk("time in ms to search %d elements: %lld\n", n, current_timestamp()-last_saved_time);

		// delete items from bst
		last_saved_time = current_timestamp();
		for (k=n; k >= 0; k--){
			bst_remove(k, bst);
		}
		printk("time in ms to delete %d elements: %lld\n", n, current_timestamp()-last_saved_time);
		bst_free(bst);
		printk("removed bst\n");
	}
}

int __init bst_module_init(void){
	printk("bst module init\n");
	bst_insert_search_delete(383);
	return 0;
}

void __exit bst_module_cleanup(void){
	printk("bst module exit\n");
}

module_init(bst_module_init);
module_exit(bst_module_cleanup);
MODULE_LICENSE("GPL");
Thank you for your time!
 
Old 12-02-2019, 03:19 AM   #2
godsfame
LQ Newbie
 
Registered: Dec 2019
Posts: 2

Original Poster
Rep: Reputation: Disabled
Hey guys,

Looks like through some testing it looks like the kernel crashes while inserting the elements but I am not sure why.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Slackware64 14.2 + kernel-generic-4.4.111 + microcode + NVIDIA-Linux-x86_64-384.111.run kjhambrick Slackware 20 01-23-2018 06:39 AM
CSS for group of HTML elements in a series of such elements Turbocapitalist Linux - General 17 09-20-2017 12:16 AM
In Javascript How to replace elements in one object with elements from another object pizzipie Linux - Software 1 05-08-2014 02:28 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 04:08 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration