⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elib_malloc.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 4 页
字号:
	x->parent->right = y;    else {	RBT_ASSERT(x == x->parent->left);	x->parent->left = y;    }    y->right = x;    x->parent = y;}/* * Replace node x with node y * NOTE: block header of y is not changed */static ERTS_INLINE voidreplace(RBTree_t **root, RBTree_t *x, RBTree_t *y){    if (!x->parent) {	RBT_ASSERT(*root == x);	*root = y;    }    else if (x == x->parent->left)	x->parent->left = y;    else {	RBT_ASSERT(x == x->parent->right);	x->parent->right = y;    }    if (x->left) {	RBT_ASSERT(x->left->parent == x);	x->left->parent = y;    }    if (x->right) {	RBT_ASSERT(x->right->parent == x);	x->right->parent = y;    }    y->flags	= x->flags;    y->parent	= x->parent;    y->right	= x->right;    y->left	= x->left;    DESTROY_TREE_NODE(x);}static voidtree_insert_fixup(RBTree_t *blk){    RBTree_t *x = blk, *y;    /*     * Rearrange the tree so that it satisfies the Red-Black Tree properties     */    RBT_ASSERT(x != root && IS_RED(x->parent));    do {	/*	 * x and its parent are both red. Move the red pair up the tree	 * until we get to the root or until we can separate them.	 */	RBT_ASSERT(IS_RED(x));	RBT_ASSERT(IS_BLACK(x->parent->parent));	RBT_ASSERT(x->parent->parent);	if (x->parent == x->parent->parent->left) {	    y = x->parent->parent->right;	    if (IS_RED(y)) {		SET_BLACK(y);		x = x->parent;		SET_BLACK(x);		x = x->parent;		SET_RED(x);	    }	    else {		if (x == x->parent->right) {		    x = x->parent;		    left_rotate(&root, x);		}		RBT_ASSERT(x == x->parent->parent->left->left);		RBT_ASSERT(IS_RED(x));		RBT_ASSERT(IS_RED(x->parent));		RBT_ASSERT(IS_BLACK(x->parent->parent));		RBT_ASSERT(IS_BLACK(y));		SET_BLACK(x->parent);		SET_RED(x->parent->parent);		right_rotate(&root, x->parent->parent);		RBT_ASSERT(x == x->parent->left);		RBT_ASSERT(IS_RED(x));		RBT_ASSERT(IS_RED(x->parent->right));		RBT_ASSERT(IS_BLACK(x->parent));		break;	    }	}	else {	    RBT_ASSERT(x->parent == x->parent->parent->right);	    y = x->parent->parent->left;	    if (IS_RED(y)) {		SET_BLACK(y);		x = x->parent;		SET_BLACK(x);		x = x->parent;		SET_RED(x);	    }	    else {		if (x == x->parent->left) {		    x = x->parent;		    right_rotate(&root, x);		}		RBT_ASSERT(x == x->parent->parent->right->right);		RBT_ASSERT(IS_RED(x));		RBT_ASSERT(IS_RED(x->parent));		RBT_ASSERT(IS_BLACK(x->parent->parent));		RBT_ASSERT(IS_BLACK(y));		SET_BLACK(x->parent);		SET_RED(x->parent->parent);		left_rotate(&root, x->parent->parent);		RBT_ASSERT(x == x->parent->right);		RBT_ASSERT(IS_RED(x));		RBT_ASSERT(IS_RED(x->parent->left));		RBT_ASSERT(IS_BLACK(x->parent));		break;	    }	}    } while (x != root && IS_RED(x->parent));    SET_BLACK(root);}static voidunlink_free_block(Block_t *del){    Uint spliced_is_black;    RBTree_t *x, *y, *z = (RBTree_t *) del;    RBTree_t null_x; /* null_x is used to get the fixup started when we			splice out a node without children. */    null_x.parent = NULL;#ifdef HARD_DEBUG    check_tree(0);#endif    /* Remove node from tree... */    /* Find node to splice out */    if (!z->left || !z->right)	y = z;    else	/* Set y to z:s successor */	for(y = z->right; y->left; y = y->left);    /* splice out y */    x = y->left ? y->left : y->right;    spliced_is_black = IS_BLACK(y);    if (x) {	x->parent = y->parent;    }    else if (!x && spliced_is_black) {	x = &null_x;	x->flags = 0;	SET_BLACK(x);	x->right = x->left = NULL;	x->parent = y->parent;	y->left = x;    }    if (!y->parent) {	RBT_ASSERT(root == y);	root = x;    }    else if (y == y->parent->left)	y->parent->left = x;    else {	RBT_ASSERT(y == y->parent->right);	y->parent->right = x;    }    if (y != z) {	/* We spliced out the successor of z; replace z by the successor */	replace(&root, z, y);    }    if (spliced_is_black) {	/* We removed a black node which makes the resulting tree	   violate the Red-Black Tree properties. Fixup tree... */	while (IS_BLACK(x) && x->parent) {	    /*	     * x has an "extra black" which we move up the tree	     * until we reach the root or until we can get rid of it.	     *	     * y is the sibbling of x	     */	    if (x == x->parent->left) {		y = x->parent->right;		RBT_ASSERT(y);		if (IS_RED(y)) {		    RBT_ASSERT(y->right);		    RBT_ASSERT(y->left);		    SET_BLACK(y);		    RBT_ASSERT(IS_BLACK(x->parent));		    SET_RED(x->parent);		    left_rotate(&root, x->parent);		    y = x->parent->right;		}		RBT_ASSERT(y);		RBT_ASSERT(IS_BLACK(y));		if (IS_BLACK(y->left) && IS_BLACK(y->right)) {		    SET_RED(y);		    x = x->parent;		}		else {		    if (IS_BLACK(y->right)) {			SET_BLACK(y->left);			SET_RED(y);			right_rotate(&root, y);			y = x->parent->right;		    }		    RBT_ASSERT(y);		    if (IS_RED(x->parent)) {			SET_BLACK(x->parent);			SET_RED(y);		    }		    RBT_ASSERT(y->right);		    SET_BLACK(y->right);		    left_rotate(&root, x->parent);		    x = root;		    break;		}	    }	    else {		RBT_ASSERT(x == x->parent->right);		y = x->parent->left;		RBT_ASSERT(y);		if (IS_RED(y)) {		    RBT_ASSERT(y->right);		    RBT_ASSERT(y->left);		    SET_BLACK(y);		    RBT_ASSERT(IS_BLACK(x->parent));		    SET_RED(x->parent);		    right_rotate(&root, x->parent);		    y = x->parent->left;		}		RBT_ASSERT(y);		RBT_ASSERT(IS_BLACK(y));		if (IS_BLACK(y->right) && IS_BLACK(y->left)) {		    SET_RED(y);		    x = x->parent;		}		else {		    if (IS_BLACK(y->left)) {			SET_BLACK(y->right);			SET_RED(y);			left_rotate(&root, y);			y = x->parent->left;		    }		    RBT_ASSERT(y);		    if (IS_RED(x->parent)) {			SET_BLACK(x->parent);			SET_RED(y);		    }		    RBT_ASSERT(y->left);		    SET_BLACK(y->left);		    right_rotate(&root, x->parent);		    x = root;		    break;		}	    }	}	SET_BLACK(x);	if (null_x.parent) {	    if (null_x.parent->left == &null_x)		null_x.parent->left = NULL;	    else {		RBT_ASSERT(null_x.parent->right == &null_x);		null_x.parent->right = NULL;	    }	    RBT_ASSERT(!null_x.left);	    RBT_ASSERT(!null_x.right);	}	else if (root == &null_x) {	    root = NULL;	    RBT_ASSERT(!null_x.left);	    RBT_ASSERT(!null_x.right);	}    }    DESTROY_TREE_NODE(del);#ifdef HARD_DEBUG    check_tree(0);#endif}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * "Address order best fit" specific callbacks.                              *\*                                                                           */static voidlink_free_block(Block_t *block){    RBTree_t *blk = (RBTree_t *) block;    Uint blk_sz = BLK_SZ(blk);    blk->flags	= 0;    blk->left	= NULL;    blk->right	= NULL;    if (!root) {	blk->parent = NULL;	SET_BLACK(blk);	root = blk;    } else {	RBTree_t *x = root;	while (1) {	    Uint size;	    size = BLK_SZ(x);	    if (blk_sz < size || (blk_sz == size && blk < x)) {		if (!x->left) {		    blk->parent = x;		    x->left = blk;		    break;		}		x = x->left;	    }	    else {		if (!x->right) {		    blk->parent = x;		    x->right = blk;		    break;		}		x = x->right;	    }	}	/* Insert block into size tree */	RBT_ASSERT(blk->parent);	SET_RED(blk);	if (IS_RED(blk->parent)) {	    tree_insert_fixup(blk);	}    }#ifdef HARD_DEBUG    check_tree(0);#endif}static Block_t *get_free_block(Uint size){    RBTree_t *x = root;    RBTree_t *blk = NULL;    Uint blk_sz;    while (x) {	blk_sz = BLK_SZ(x);	if (blk_sz < size) {	    x = x->right;	}	else {	    blk = x;	    x = x->left;	}    }        if (!blk)	return NULL;#ifdef HARD_DEBUG    ASSERT(blk == check_tree(size));#endif    unlink_free_block((Block_t *) blk);    return (Block_t *) blk;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Debug functions                                                           *\*                                                                           */#ifdef HARD_DEBUG#define IS_LEFT_VISITED(FB)	((FB)->flags & LEFT_VISITED_FLG)#define IS_RIGHT_VISITED(FB)	((FB)->flags & RIGHT_VISITED_FLG)#define SET_LEFT_VISITED(FB)	((FB)->flags |= LEFT_VISITED_FLG)#define SET_RIGHT_VISITED(FB)	((FB)->flags |= RIGHT_VISITED_FLG)#define UNSET_LEFT_VISITED(FB)	((FB)->flags &= ~LEFT_VISITED_FLG)#define UNSET_RIGHT_VISITED(FB)	((FB)->flags &= ~RIGHT_VISITED_FLG)#if 0#  define PRINT_TREE#else#  undef PRINT_TREE#endif#ifdef PRINT_TREEstatic void print_tree(void);#endif/* * Checks that the order between parent and children are correct, * and that the Red-Black Tree properies are satisfied. if size > 0, * check_tree() returns a node that satisfies "best fit" resp. * "address order best fit". * * The Red-Black Tree properies are: *   1. Every node is either red or black. *   2. Every leaf (NIL) is black. *   3. If a node is red, then both its children are black. *   4. Every simple path from a node to a descendant leaf *      contains the same number of black nodes. */static RBTree_t *check_tree(Uint size){    RBTree_t *res = NULL;    Sint blacks;    Sint curr_blacks;    RBTree_t *x;#ifdef PRINT_TREE    print_tree();#endif    if (!root)	return res;    x = root;    ASSERT(IS_BLACK(x));    ASSERT(!x->parent);    curr_blacks = 1;    blacks = -1;    while (x) {	if (!IS_LEFT_VISITED(x)) {	    SET_LEFT_VISITED(x);	    if (x->left) {		x = x->left;		if (IS_BLACK(x))		    curr_blacks++;		continue;	    }	    else {		if (blacks < 0)		    blacks = curr_blacks;		ASSERT(blacks == curr_blacks);	    }	}	if (!IS_RIGHT_VISITED(x)) {	    SET_RIGHT_VISITED(x);	    if (x->right) {		x = x->right;		if (IS_BLACK(x))		    curr_blacks++;		continue;	    }	    else {		if (blacks < 0)		    blacks = curr_blacks;		ASSERT(blacks == curr_blacks);	    }	}	if (IS_RED(x)) {	    ASSERT(IS_BLACK(x->right));	    ASSERT(IS_BLACK(x->left));	}	ASSERT(x->parent || x == root);	if (x->left) {	    ASSERT(x->left->parent == x);	    ASSERT(BLK_SZ(x->left) < BLK_SZ(x)		   || (BLK_SZ(x->left) == BLK_SZ(x) && x->left < x));	}	if (x->right) {	    ASSERT(x->right->parent == x);	    ASSERT(BLK_SZ(x->right) > BLK_SZ(x)		   || (BLK_SZ(x->right) == BLK_SZ(x) && x->right > x));	}	if (size && BLK_SZ(x) >= size) {	    if (!res		|| BLK_SZ(x) < BLK_SZ(res)		|| (BLK_SZ(x) == BLK_SZ(res) && x < res))		res = x;	}	UNSET_LEFT_VISITED(x);	UNSET_RIGHT_VISITED(x);	if (IS_BLACK(x))	    curr_blacks--;	x = x->parent;    }    ASSERT(curr_blacks == 0);    UNSET_LEFT_VISITED(root);    UNSET_RIGHT_VISITED(root);    return res;}#ifdef PRINT_TREE#define INDENT_STEP 2#include <stdio.h>static voidprint_tree_aux(RBTree_t *x, int indent){    int i;    if (!x) {	for (i = 0; i < indent; i++) {	    putc(' ', stderr);	}	fprintf(stderr, "BLACK: nil\r\n");    }    else {	print_tree_aux(x->right, indent + INDENT_STEP);	for (i = 0; i < indent; i++) {	    putc(' ', stderr);	}	fprintf(stderr, "%s: sz=%lu addr=0x%lx\r\n",		IS_BLACK(x) ? "BLACK" : "RED",		BLK_SZ(x),		(Uint) x);	print_tree_aux(x->left,  indent + INDENT_STEP);    }}static voidprint_tree(void){    fprintf(stderr, " --- Size-Adress tree begin ---\r\n");    print_tree_aux(root, 0);    fprintf(stderr, " --- Size-Adress tree end ---\r\n");}#endif#endif#endif /* ENABLE_ELIB_MALLOC */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -