static wtreeNode_t* insert_rc(wtreeRoot_t* root, wtreeNode_t* parent, wtreeNode_t* item, BOOL compact, int* depth) { if(!root || !item) return parent; if(!parent) { if(root->adapter->onadded) root->adapter->onadded(item, root->ext_ctx); return item; } if(depth) { (*depth)++; } if(parent->top < item->top) { if((item->top - item->size) == parent->top) { if(item->base_size) { item->base_size += parent->base_size; } else if(parent->base_size) { parent->right = insert_rc(root, parent->right, item, compact,depth); parent = merge_next(root,parent); parent = resolve(root, parent, compact); return parent; } item->size += parent->size; item->left = parent->left; item->right = parent->right; if(root->adapter->onremoved) root->adapter->onremoved(parent, root->ext_ctx, TRUE); if(root->adapter->onadded) root->adapter->onadded(item, root->ext_ctx); parent = item; } else { parent->right = insert_rc(root, parent->right, item, compact,depth); parent = merge_next(root, parent); parent = resolve(root, parent, compact); } return parent; } else { if((parent->top - parent->size) == item->top) { if(parent->base_size) { parent->base_size += item->base_size; } else if(item->base_size) { parent->left = insert_rc(root, parent->left, item, compact,depth); parent = merge_prev(root, parent); parent = resolve(root, parent, compact); return parent; } parent->size += item->size; } else { parent->left = insert_rc(root, parent->left, item, compact,depth); parent = merge_prev(root, parent); parent = resolve(root, parent, compact); return parent; } return parent; } }
static wtreeNode_t* purge_rc(wtreeRoot_t* root, wtreeNode_t* node) { if(!root) return NULL; if(node->right) { node->right = purge_rc(root, node->right); node = merge_next(root, node); } if(node->left) { node->left = purge_rc(root, node->left); node = merge_prev(root, node); } if (node->size == node->base_size) { if(node->left && (node->left->base_size != node->left->size)) { node = rotate_right(node); node->right = purge_rc(root, node->right); } else if(node->right && (node->right->base_size != node->right->size)) { node = rotate_left(node); node->left = purge_rc(root, node->left); } else if(!node->left && !node->right) { if(root->adapter->onfree) { if(root->adapter->onremoved) root->adapter->onremoved(node, root->ext_ctx, FALSE); root->adapter->onfree(node->top - node->base_size, node->base_size,node, root->ext_ctx); return NULL; } } } return node; }
static wtreeNode_t* grows_node(wtreeRoot_t* root, wtreeNode_t* parent, wtreeNode_t** grown, uint32_t nsz) { if(!parent) { parent = *grown; *grown = NULL; if(root->adapter->onadded) root->adapter->onadded(parent, root->ext_ctx); return parent; } if((*grown)->top == (parent->top - parent->size)) { if((parent->size + root->hdr_sz) > (nsz - (*grown)->size)) { parent->size -= (nsz - (*grown)->size); return parent; } // return requested node to its base node or neighbor parent->size += (*grown)->size; grown = NULL; return parent; } else if((*grown)->top > parent->top) { parent->right = grows_node(root, parent->right, grown, nsz); parent = merge_next(root, parent); parent = resolve(root, parent, FALSE); } else { parent->left = grows_node(root, parent->left, grown, nsz); parent = merge_prev(root, parent); parent = resolve(root, parent, FALSE); } return parent; }
static wtreeNode_t* merge_prev(wtreeRoot_t* root, wtreeNode_t* merger) { if(!merger) return NULL; if(!merger->left) return merger; merger->left = merge_prev(root, merger->left); merger->left = merge_from_rightend(root, merger->left, merger); return merger; }
static wtreeNode_t* resolve(wtreeRoot_t* root, wtreeNode_t* parent, BOOL compact) { if (!parent) return NULL; if (parent->right && parent->left) { if (!(parent->right->size > parent->size) && !(parent->left->size > parent->size)) return parent; if (parent->right->size > parent->left->size) { parent = rotate_left(parent); parent->left = resolve(root,parent->left,compact); parent = merge_prev(root, parent); } else { parent = rotate_right(parent); parent->right = resolve(root,parent->right,compact); parent = merge_next(root, parent); } return parent; } else if (parent->right) { if (parent->right->size > parent->size) { parent = rotate_left(parent); parent->left = resolve(root,parent->left,compact); parent = merge_prev(root, parent); } return parent; } else if (parent->left) { if (parent->left->size > parent->size) { parent = rotate_right(parent); parent->right = resolve(root, parent->right,compact); parent = merge_next(root, parent); } return parent; } else { if (!parent->size && !parent->base_size){ return NULL; }else if(parent->size == parent->base_size) { if(root->adapter->onfree && compact) { if(root->adapter->onremoved) root->adapter->onremoved(parent,root->ext_ctx, FALSE); root->adapter->onfree(parent->top - parent->base_size, parent->base_size, parent, root->ext_ctx); return NULL; } } } return parent; }
void kfree(void *ptr) { struct header *header = (struct header *)((u32)ptr - sizeof(struct header)); if (header->magic != MAGIC_CHECK) { printk ("Memory corruption!\n"); return; } header->used = 0; if (header->next && header->next->used == 0) merge_next(header); if(header->prev && header->prev->used == 0) merge_prev(header); print_blocks(); }