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

📄 alloctree.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
  register uint32_t newMask;    if (treeKey == tree->lastRemove->value)    /*  note that if tree->lastRemove == TREE_NIL, lastInsert->value     * will never match treeKey, so tree_find will be run..     */    theNode = tree->lastRemove;  else    theNode = tree_find(tree->root,treeKey);  assert(theNode != NULL);    /* See if the OID in question is in the tree: */  if (theNode == TREE_NIL) {    DEBUG(dealloc)      kdprintf(KR_OSTREAM,	       "allocTree_removeOID passed OID 0x"DW_HEX", "	       "which does not have a treenode\n",	       DW_HEX_ARG(oid));    return 0; /* RETURN "object not within tree" */  }  tree->lastRemove = theNode; /* store it for next time */  curMap = theNode->body.map[offset];    if (curMap == 0) { /* empty */    DEBUG(dealloc)      kdprintf(KR_OSTREAM,	       "allocTree_removeOID passed OID 0x"DW_HEX", "	       "whose frame is not part of this tree\n",	       DW_HEX_ARG(oid));    return 0; /* RETURN "object not within tree" */  }#ifndef TREE_NO_TYPES#ifndef NDEBUG  if (theNode->body.type[offset] != type) {    debug_print_node(theNode);    kpanic(KR_OSTREAM,	   "allocTree_removeOID passed OID 0x"DW_HEX", whose "	   "type (%s)is not the same as the one passed in (%s)\n",	   DW_HEX_ARG(oid),	   theNode->body.type[offset],	   type);    return 0; /* RETURN "object has wrong type" */  }#endif#endif  newMask = (1 << objNum);    if ( (curMap & newMask) != newMask) {    DEBUG(dealloc)      kdprintf(KR_OSTREAM,	       "allocTree_removeOID passed OID 0x"DW_HEX", "	       "who is not marked allocated in its map (0x%04x)\n",	       DW_HEX_ARG(oid),	       curMap);    return 0; /* RETURN "object not allocated" */  }  DEBUG(dealloc)    kprintf(KR_OSTREAM,	    "Deallocating %s 0x"DW_HEX", whose frame has "	     "map 0x%04x (before)\n",	    type_name(type),	    DW_HEX_ARG(oid),	    curMap);  curMap &= ~newMask;    if (curMap == 0) {    /* this part of the node is completele deallocated -- check if the     * whole node is empty, too, and if so, delete it from the tree.     */    uint32_t x;    DEBUG(dealloc)      kprintf(KR_OSTREAM,	      "Frame empty -- checking if everything is empty\n");    /* invalidate the offset */    theNode->body.map[offset] = 0u; #ifndef TREE_NO_TYPES    theNode->body.type[offset] = SBOT_INVALID;#endif    /* check if we are empty */    x = SB_FRAMES_PER_TREENODE;    while (x > 0) {      x--;      if (theNode->body.map[x] != 0u) {	x = SB_FRAMES_PER_TREENODE;	break; /* BREAK "Nope, not empty yet!" */      }    }        if (x == 0) {      /* completely empty */      DEBUG(dealloc)	kprintf(KR_OSTREAM,		"TREENODE empty -- deleting it\n");      _allocTree_clearCachedInfo(tree); /* we are going to be deleting*/      /* remove the node */      tree->root = tree_remove(tree->root, theNode);      /* since object pointed to by lastRemove is now ancient history,	 nil that out: */      tree->lastRemove = TREE_NIL;      /* It may happen (has happened!) that this tree node we are	 about to delete is also the most recently *inserted* node.	 If so, we must nil that out too lest a deleted node get stuck	 into the tree somehow. */      if (tree->lastInsert == theNode)	tree->lastInsert = TREE_NIL;            /* and delete it */      tree_deleteNode(theNode);    }    /* release the now empty frame */    DEBUG(limit)      kprintf(KR_OSTREAM,	      "allocTree_removeOID unreserving frame for oid "	      DW_HEX"\n",	      DW_HEX_ARG(oid));	          bank_UnreserveFrames(bank, 1);    if (type == OT_Node)      ob_ReleaseNodeFrame(bank, EROS_FRAME_FROM_OID(oid));    else      ob_ReleasePageFrame(bank, EROS_FRAME_FROM_OID(oid));  } else {    theNode->body.map[offset] = curMap; /*					 * put in the new map					 */    DEBUG(dealloc)      kprintf(KR_OSTREAM,	      "Wrote new map 0x%04x\n",curMap);  }  return 1; /* RETURN "success" */}uint32_tallocTree_IncrementalDestroy(TREE *toDie, OID *retFrame){  if (toDie->root == TREE_NIL) {    toDie->lastInsert = TREE_NIL;    toDie->lastRemove = TREE_NIL;        return 0; /* RETURN "there is no more left!" */  } else {    TREENODE *curNode = toDie->root;    OID oid;    uint32_t index;        oid = curNode->value;    for (index = 0; index < SB_FRAMES_PER_TREENODE; index++) {      if (curNode->body.map[index] != 0u) {	if (retFrame) *retFrame = oid + index * EROS_OBJECTS_PER_FRAME;	oid++;#ifndef TREE_NO_TYPES	curNode->body.type[index] = SBOT_INVALID;#endif	curNode->body.map[index] = 0u;	index++; /* increment past this one, as we know it is zero */	break;      }    }    /* skip past any empty ones after this one */    while (index < SB_FRAMES_PER_TREENODE	   && curNode->body.map[index] == 0u) {      index++;    }    if (index == SB_FRAMES_PER_TREENODE) {      /* this node is finished */      /* we are going to be deleting */            _allocTree_clearCachedInfo(toDie);       toDie->root = tree_remove(toDie->root, curNode);      /* SHAP: and delete it */      tree_deleteNode(curNode);    }    return 1; /* RETURN "got some" */  }  }uint32_tallocTree_mergeTrees(TREE *dest, TREE *src){  TREENODE *curNode = src->root;  if (src == dest)    kpanic(KR_OSTREAM,"AllocTree.c:%d: Merging identical trees!\n",__LINE__);  _allocTree_clearCachedInfo(src); /* we are going to be deleting */    while (curNode != TREE_NIL) {    /*   loop through the tree, removing the root of /src/ and     * inserting it's contents into /dest/     */    TREENODE *destNode;        src->root = tree_remove(src->root,curNode);        destNode = tree_find(dest->root,curNode->value);    if (destNode == TREE_NIL) {      /* not there - insert it */      dest->root = tree_insert(dest->root,curNode);    } else {      /* there -- merge the old and new */      uint32_t idx;      for (idx = 0; idx < SB_FRAMES_PER_TREENODE; idx++) {	if (curNode->body.map[idx] != 0) {#ifdef PARANOID	  if (destNode->body.map[idx] != 0) {	    debug_print_node(curNode);	    debug_print_node(destNode);	    /* conflict */	    kpanic(KR_OSTREAM,"Spacebank: treenode merge conflict\n");	  }#endif /*PARANOID*/	  	  /* write in the data */#ifndef TREE_NO_TYPES	  destNode->body.type[idx] = curNode->body.type[idx];#endif	  destNode->body.map[idx] = curNode->body.map[idx];	}      }      /* done merging, delete the node */      tree_deleteNode(curNode);    }    curNode = src->root; /* reset curNode to the new root */      } /* while (curNode != TREE_NIL) */  /* the old tree is dead, long live the tree! */  src->root = TREE_NIL;  src->lastInsert = TREE_NIL;  src->lastRemove = TREE_NIL;        /* Having done the merge, our cached information about last     insertion and removal may now be stale, but there is no point in     chucking it.  Think of the spacebank clobber that just occurred     as being "out of band" w.r.t. the normal sequence of allocations     and deletions.  If we're right we win, and if we're wrong we cost     ourselves a marginal compare, which is not a bad downside. */  return 0;}voiddebug_print_node(TREENODE *node){  uint32_t i;  kprintf(KR_OSTREAM,	  "%sNode 0x%08x Parent 0x%08x Left 0x%08x Right %08x\n",	  ((node->color == TREE_BLACK)?"Black  ":	    (node->color == TREE_RED)?"Red    ": "BADCLR "),	  node, node->parent, node->left, node->right);  kprintf(KR_OSTREAM,	  "Value: 0x%08x%08x\n",	  DW_HEX_ARG(node->value));#ifndef TREE_NO_TYPES  kprintf(KR_OSTREAM,	  "Type: ");  for (i = 0; i < SB_FRAMES_PER_TREENODE; i++)    kprintf(KR_OSTREAM, "   %02x", (uint32_t)node->body.type[i]);  kprintf(KR_OSTREAM,"\n");#endif	    kprintf(KR_OSTREAM,	  "Map:  ");  for (i = 0; i < SB_FRAMES_PER_TREENODE; i++)    kprintf(KR_OSTREAM, " %04x", (uint32_t)node->body.map[i]);  kprintf(KR_OSTREAM,"\n");}/* node comparision functions */#ifdef NO_FAST_MACRO_COMPAREstatic inttree_compare(TREENODE *t0, TREENODE *t1){  if (t0->value < t1->value)    return -1;  if (t0->value > t1->value)    return 1;  return 0;}static inttree_compare_key(TREENODE *t0, TREEKEY key){  /* NOTE: in order to be found correctly, /key/ *MUST* have   *       zeros in the low bits.  The best way to do this is   *       to AND it with ~(SB_OBJECTS_PER_TREENODE - 1) before   *       passing it to any call that uses this routine.   */  if (t0->value < key)    return -1;  if (t0->value > key)    return 1;  return 0;}#else /* ! NO_FAST_MACRO_COMPARE */ /* use macro versions of the above for speed! */#define tree_compare(t0,t1) (((t0)->value < (t1)->value)? -1 : \                             (((t0)->value > (t1)->value)? 1 : 0))#define tree_compare_key(t0,key) (((t0)->value < key)? -1 : \                                  (((t0)->value > key)? 1 : 0))#endif /* ! NO_FAST_MACRO_COMPARE */#define ERROR_PRINTF(x) kdprintf x#define ERR_FIL KR_OSTREAM#define VERB_PRINTF(x) kprintf x#define VERB_FIL KR_OSTREAM#include <rbtree/tree_init.c>#include <rbtree/tree_util.c>#include <rbtree/tree_find.c>#include <rbtree/tree_insert.c>#include <rbtree/tree_validate.c>#include <rbtree/tree_remove.c>#include <rbtree/tree_contains.c>#include <rbtree/tree_succ.c>#include <rbtree/tree_pred.c>#include <rbtree/tree_min.c>#include <rbtree/tree_max.c>

⌨️ 快捷键说明

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