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

📄 alloctree.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1998, 1999, Jonathan Adams. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <eros/target.h>#include <eros/RangeKey.h>#include <eros/Invoke.h>#include <domain/Runtime.h>#include <domain/domdbg.h>#include "debug.h"#include "misc.h"#include "assert.h"#include "constituents.h"#include "spacebank.h"#include "ObjSpace.h"#include "AllocTree.h"#include "AllocTree_Internals.h"#include "malloc.h"#include "Bank.h"#if CND_DEBUG(tree)#define VERBOSE#endif#undef TREE_STATIC_ALLOC /* NO STATIC ALLOCATION */#ifdef TREE_STATIC_ALLOC#define NUM_TREENODES 512TREENODE static_treenodes[NUM_TREENODES]; /* added to free list on					   * startup					   */#endifvoid debug_print_node(TREENODE *node);/* head of the free list -- a list of free nodes linked by their right * links. */static TREENODE *freehead = 0;TREENODE *tree_newNode(TREEKEY key){  TREENODE *newNode;    if (freehead == 0) {    TREENODE *nodes;    uint32_t x;        DEBUG(malloc) kdprintf(KR_OSTREAM, "Allocating more tree nodes\n");#ifdef TREE_STATIC_ALLOC    kpanic(KR_OSTREAM,	     "Spacebank: out of statically allocated Treenodes!\n");    return TREE_NIL;#else    #define NUM_NODES (8)        nodes = malloc(sizeof(TREENODE) * NUM_NODES);    x = NUM_NODES;    DEBUG(malloc) kdprintf(KR_OSTREAM, " ... got data at 0x%08x\n",nodes);    if (!nodes) {      kpanic(KR_OSTREAM,	     "Spacebank: mallocing Treenodes failed!\n");    }    /* add all of the new nodes to the freelist */    while (x) {      nodes[--x].parent = freehead;      freehead = &nodes[x];    }#undef NUM_NODES#endif  }  newNode = freehead;  freehead = newNode->parent;  {    /* initialize value */    uint32_t x;        newNode->left = TREE_NIL;    newNode->right = TREE_NIL;    newNode->parent = TREE_NIL;    newNode->color = TREE_BLACK;    newNode->value = key;    /* initialize body */    for (x = 0; x < SB_FRAMES_PER_TREENODE; x++) {      newNode->body.map[x] = 0u;#ifndef TREE_NO_TYPES      newNode->body.type[x] = SBOT_INVALID;#endif          }  }  return newNode;  }inttree_deleteNode(TREENODE *node){  if (node != NULL && node != TREE_NIL) {    node->parent = freehead; /* link it in to free list */    freehead = node;        /* then put it as head.    */        return 1;      } else {    return 0;  }    }/* allocTree functions */static void_allocTree_clearCachedInfo(TREE *target);/*   Clears any cached info in /target/ -- should be called any time a * node is going to be deleted from a tree, as this can make the * cached info incorrect. */uint32_tallocTree_Init(TREE *tree){  static uint32_t inited = 0;  if (!inited && (inited = 1) == 1 ) { /* run only once */    tree_init();    TREE_NIL->value = 1u; /* to match no possible value */  #ifndef TREE_STATIC_ALLOC    freehead = 0;#else /*TREE_STATIC_ALLOC*/    {      /* set up free list */      int x;            freehead = &static_treenodes[0]; /* the first node it our head */            for (x = 0; x < NUM_TREENODES - 1; x++) {	static_treenodes[x].parent = &static_treenodes[x+1];	/* each node points to the next one. */      }            /* special case -- last node points to 0 */      static_treenodes[x].parent = 0;    }#endif  }  tree->root = TREE_NIL; /* initialize the tree */  _allocTree_clearCachedInfo(tree);  return 0;}static void_allocTree_clearCachedInfo(TREE *target){  if (target) {    target->lastInsert = TREE_NIL;    target->lastRemove = TREE_NIL;  }}uint32_tallocTree_insertOIDs(TREE *tree, uint8_t type, OID oid, uint32_t count){  register uint32_t curMap;  register uint32_t newMask;    TREENODE *theNode = TREE_NIL;  OID treeKey = FLOOR2(oid, SB_OBJECTS_PER_TREENODE);  uint32_t offset = MOD2(oid / EROS_OBJECTS_PER_FRAME, SB_FRAMES_PER_TREENODE);  uint32_t objNum = oid & (EROS_OBJECTS_PER_FRAME - 1);  if (treeKey == tree->lastInsert->value)    /*  note that if tree->lastInsert == TREE_NIL, lastInsert->value     * will never match treeKey, so tree_find will be run..     */    theNode = tree->lastInsert;  else    theNode = tree_find(tree->root,treeKey);  if (theNode == TREE_NIL) {    theNode = tree_newNode(treeKey);    /* initialized the node -- now add it to the tree */    tree->root = tree_insert(tree->root, theNode);  }  tree->lastInsert = theNode; /* store it for next time */  #ifndef TREE_NO_TYPES#ifndef NDEBUT  /* make sure the types match */  if (theNode->body.type[offset] != SBOT_INVALID      && (theNode->body.type[offset] != type	  && theNode->body.map[offset] != 0u         )) {    debug_print_node(theNode);    kpanic(KR_OSTREAM,	     "Spacebank: allocTree_insert at 0x"DW_HEX" got type "	     "conflict.  Offset %u says \n"	     "           type %u, but caller says type %s!\n",	     DW_HEX_ARG(treeKey),	     offset,	     (uint32_t)theNode->body.type[offset],	     type_name(type)	    );    return 0; /* RETURN -- "error" */  }#endif#endif  DEBUG(alloc)    if (!valid_type(type)) {      kpanic(KR_OSTREAM,	     "Spacebank: allocTree_insert(0x"DW_HEX") got sent "	     "invalid type %u\n",	     DW_HEX_ARG(oid),	     type	     );      return 0; /* RETURN -- "error" */    }  /*  DEBUG(alloc)*/ if (1)     if (count + objNum > objects_per_frame[type]) {      debug_print_node(theNode);      kpanic(KR_OSTREAM,	     "Spacebank: allocTree_insert(0x"DW_HEX",%s) got bad count\n"	     "           (objNum (%d) + count (%d) > "	                                 "objects_per_frame[] (%d)\n",	     DW_HEX_ARG(oid),	     type_name(type),	     objNum,	     count,	     objects_per_frame[type]	    );      return 0; /* RETURN -- "error" */    }  curMap = theNode->body.map[offset]; /* get it from the node */  /* muck with it */#ifndef TREE_NO_TYPES  if (curMap == 0u) {    /* re-type the node */    theNode->body.type[offset] = type;    curMap = 0u; /* currently redundant -- might change later */    /* could possibly be object_map_mask, but that makes tests slow */  }#endif  newMask = (((1u << count) - 1) << objNum);  /* test whether there are any ones where the mask is */  if ( (curMap & newMask ) ) {    debug_print_node(theNode);    kpanic(KR_OSTREAM,	   "Spacebank: allocTree_insert(0x"DW_HEX") "	   "attempted to exceed type frame count limit\n"	   "curMap: 0x%04x, new mask: %04x full map: %04x\n",	   DW_HEX_ARG(oid),	   curMap, newMask, objects_map_mask[type]);  }  /*  kprintf(KR_OSTREAM,	  "SpaceBank:  AllocTree for 0x"DW_HEX" frame 0x%02x old "	  "count %d new count %d\n",	  DW_HEX_ARG(treeKey),	  (uint32_t)offset,	  curCount,	  curCount + count);   */  /* FIXME: faster to do it directly? */    curMap |= newMask;    theNode->body.map[offset] = curMap; /* write it to				       * theNode.				       */  return 1; /* RETURN -- "done" */}uint32_tallocTree_checkForOID(TREE *tree, OID oid){  TREENODE *theNode;  OID treeKey = FLOOR2(oid, SB_OBJECTS_PER_TREENODE);  uint32_t offset = MOD2(oid / EROS_OBJECTS_PER_FRAME, SB_FRAMES_PER_TREENODE);  uint32_t objNum = oid & (EROS_OBJECTS_PER_FRAME - 1);  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);  if (theNode == TREE_NIL) {    return 0;	  }  tree->lastRemove = theNode;  return (theNode->body.map[offset] & (1 << objNum));}uint32_tallocTree_removeOID(TREE *tree, struct Bank *bank, uint8_t type, OID oid){  TREENODE *theNode;  OID treeKey = FLOOR2(oid, SB_OBJECTS_PER_TREENODE);  uint32_t offset = MOD2(oid / EROS_OBJECTS_PER_FRAME, SB_FRAMES_PER_TREENODE);  uint32_t objNum = oid & (EROS_OBJECTS_PER_FRAME - 1);  register uint32_t curMap;

⌨️ 快捷键说明

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