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

📄 bank.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
}uint32_tBankDestroyBankAndStorage(Bank *bank, bool andStorage){  /* the way this works is a depth-first deallocation: we first delete   * (effectively recursively, actually in-place) all of the children   * of a bank, then delete the bank itself.  Of course, if one of the   * children of that bank has children, those get deleted first,   * etc.  The deletion stops when we delete /bank/.   *   * NOTE that there is a perverse piece of nonsense that we are   * taking advantage of here: the space occupied by the node(s) of a   * given bank are part of that bank's allocated tree.   */#ifdef PARANOID  if (bank == &primebank || bank == &bank0)    kpanic(KR_OSTREAM, "spacebank: attempt to destroy primebank/bank0\n");#endif  DEBUG(children)    kprintf(KR_OSTREAM,	    "DestroyBank: Destroying bank 0x%08x%s\n",	    bank,	    (andStorage)?" and storage":" and returning storage to parent");  /* destroy this bank and all of its children */  {    Bank *curBank = 0;    Bank *parentBank = bank->parent;    Bank *next;    while (bank) {      if (curBank == 0)	curBank = bank;          while (curBank->firstChild)	curBank = curBank->firstChild;      /* curbank now points to a leftmost child */      next = curBank->nextSibling;      FlushBankCache(curBank);      /* rescind all outstanding red segment nodes that point to this	 bank */      {	/* FIX: There is a HUGE problem here -- if the underlying	   range is unavailable (e.g. dismounted) then this operation	   will fail! */		int i;	for (i = 0; i < BANKPREC_NUM_PRECLUDES; i++) {	  if (curBank->exists[i]) {	    uint32_t result;	    result = range_getobjectkey(KR_SRANGE,					OT_Node,					curBank->limitedKey[i],					KR_TMP);	    if (result != RC_OK) {	      DEBUG(children)		kprintf(KR_OSTREAM,			"SpaceBank: Unable to create key to limited "			"node %d oid 0x"DW_HEX" (0x%08x)\n",			i,			DW_HEX_ARG(curBank->limitedKey[i]),			result);	    }	    	    /* It will do no harm to rescind it if we didn't get it */	    result = range_rescind(KR_SRANGE, KR_TMP);	    if (result != RC_OK) {	      DEBUG(children)		kprintf(KR_OSTREAM,			"SpaceBank: Unable to create key to limited "			"node %d oid 0x"DW_HEX" (0x%08x)\n",			i,			DW_HEX_ARG(curBank->limitedKey[i]),			result);	    }	    	    result = allocTree_removeOID(&curBank->allocTree,					 curBank,					 OT_Node,					 curBank->limitedKey[i]);	    if (result == 0) {	      /* failed */	      DEBUG(children)		kprintf(KR_OSTREAM,			"SpaceBank: Unable to remove allocTree entry of "			"node %d oid 0x"DW_HEX"\n",			i,			DW_HEX_ARG(curBank->limitedKey[i]));	    }	  }	}      }      if (andStorage)	DestroyStorage(curBank);      else	allocTree_mergeTrees(&parentBank->allocTree,&curBank->allocTree);      /* unlink the bank we are blowing away */      curBank->parent->firstChild = curBank->nextSibling;      /* blow it away */      free_bank(curBank);            if (curBank == bank)	bank = 0;            if (next)	curBank = next;      else	curBank = bank;    }  }    return RC_OK;}/* FIXED BY SHAP -- this function has no need to grok the message   structure. */uint32_tBankAllocObjects(Bank *bank, uint8_t type, uint8_t number, uint32_t kr){  int retval = 0;  struct Bank_MOFrame *obj_frame;  uint32_t count = 0;  uint32_t i;  uint64_t oids[3];#ifdef PARANOID    if (number < 1 || number > 3) {    kpanic(KR_OSTREAM,	     "SpaceBank: asked for strange number (%i) of"	     " objects of type %i\n",	     (int)number,(int)type);  }#endif  obj_frame = bank_getTypeFrame(bank, type);  if (obj_frame == NULL) {    /* single frame per object type -- preallocate all objects */    if (bank_ReserveFrames(bank, number) != RC_OK) {      return RC_SB_LimitReached;    }  }    while(count < number) {    uint64_t newFrame;    uint32_t retVal;    /* take care of frame stuff */    if (obj_frame) {      if (obj_frame->frameMap != 0u) {	uint32_t offset = ffs(obj_frame->frameMap) - 1;	OID oid = obj_frame->frameOid | offset;	obj_frame->frameMap &= ~(1u << offset);	oids[count++] = oid;	DEBUG(alloc)	  kprintf(KR_OSTREAM,		   "Allocated %s oid=0x%08x%08x. Map now 0x%08x\n",		   type_name(type),		   (uint32_t) (oid >> 32),		   (uint32_t) oid,		   obj_frame->frameMap);	continue;      }      /* need to grab another frame. -- reserve it first */      if (bank_ReserveFrames(bank, 1u) != RC_OK) 	goto cleanup;    }        DEBUG(alloc) kprintf(KR_OSTREAM, "spacebank: allocating new frame\n");    if (type == OT_Node)      retVal = ob_AllocNodeFrame(bank, &newFrame);    else      retVal = ob_AllocPageFrame(bank, &newFrame);    if (retVal != RC_OK)      goto cleanup;    /* got some space in newFrame */    if (bank != &bank0)      allocTree_insertOIDs(&bank->allocTree,			   type,			   newFrame,			   objects_per_frame[type]);    if (obj_frame) {      /* shove the frame into the cache, then go back to the top to	 do the allocation */      obj_frame->frameOid = newFrame;      obj_frame->frameMap = objects_map_mask[type];      continue; /*CONTINUE*/    } else {      oids[count++] = newFrame;      continue; /*CONTINUE*/    }  }    /* now oids contains the /count/ oids -- create the keys */  for (i = 0; i < number; i++) {     DEBUG(alloc)      kprintf(KR_OSTREAM,	      "spacebank: getting object key "DW_HEX"\n",	      DW_HEX_ARG(oids[i]));        retval = range_getobjectkey(KR_SRANGE,type,oids[i],kr+i);    DEBUG(alloc)      kprintf(KR_OSTREAM,	      "spacebank: got back %x\n",	      retval);        if (retval != RC_OK) {      /* ack! we've got to undo everything!       * note that we don't need to rescind the keys we made, since they       * point to a zero object       */      goto cleanup;    }  }  bank->allocs[type] += number;    return retval;cleanup:  DEBUG(alloc)    kdprintf(KR_OSTREAM,	     "spacebank: Out of frames.\n");  while (count--)    bank_deallocOID(bank, type, oids[count]);    return RC_SB_LimitReached;}  uint32_tBankDeallocObjects(Bank *bank, uint8_t type, uint8_t count, uint32_t kr){  int i;  uint32_t retval = (1<<count) - 1; /* assume failure until proven innocent. */#ifdef PARANOID  if (count < 1 || count > 3) {    kpanic(KR_OSTREAM,	     "SpaceBank: asked to dealloc strange number (%i) of"	     " objects of type %i\n",	     (int)count,(int)type);  }#endif  for (i = 0; i < count; i++) {    OID oid;    uint32_t obType;    uint32_t k = kr + i;    uint32_t code;        code = range_identify(KR_SRANGE, k, &obType, &oid);    if (code != RC_OK) {      DEBUG(dealloc)	kdprintf(KR_OSTREAM,		 "SpaceBank: range_identify failed (%u)\n",		 code);      continue;    }    if (obType != type) {      DEBUG(dealloc)	kdprintf(KR_OSTREAM,		 "SpaceBank: Key %u has type %s, which is not the "		 "deallocation type (%s)\n",		 i,		 type_name(obType),		 type_name(type));      continue;    }        if (bank_containsOID(bank,type,oid)) {      /* It's ours */      if (range_rescind(KR_SRANGE,k) != RC_OK) {         continue; /* CONTINUE "not a strong key" */       }      if ( ! bank_deallocOID(bank,type,oid)) {         kpanic(KR_OSTREAM,                "SpaceBank: Dealloc failed after contains succedded!\n");      }      DEBUG(dealloc) {	uint32_t result, nType;	result = key_kt(k, &nType, 0);		if (result != RC_OK || nType != RC_Void) {	  /* Didn't dealloc! */	  kpanic(KR_OSTREAM,		 "spacebank: rescind successful but new keytype not "		 "Number\n"		 "           (passed in type %s, new type %d, OID "		 "0x"DW_HEX")\n",		 type,		 nType,		 DW_HEX_ARG(oid));	}      }      retval &= ~(1u << i); /* mark success */    }    else DEBUG (dealloc) {      kdprintf(KR_OSTREAM, "Bank does not contain %s 0x"DW_HEX"\n",	       type_name(type),	       DW_HEX_ARG(oid));    }  }  return retval;}uint32_tBankIdentifyObjects(Bank *bank, uint8_t type, uint8_t count, uint32_t kr){  int i;  uint32_t retval = (1<<count) - 1; /* assume failure until proven innocent. */#ifdef PARANOID  if (count < 1 || count > 3) {    kpanic(KR_OSTREAM,	     "SpaceBank: asked to dealloc strange number (%i) of"	     " objects of type %i\n",	     (int)count,(int)type);  }#endif  for (i = 0; i < count; i++) {    OID oid;    uint32_t obType;    uint32_t k = kr + i;    uint32_t code;        code = range_identify(KR_SRANGE, k, &obType, &oid);    if (code != RC_OK) {      DEBUG(dealloc)	kdprintf(KR_OSTREAM,		 "SpaceBank: range_identify failed (%u)\n",		 code);      continue;    }    if (obType != type) {      DEBUG(dealloc)	kdprintf(KR_OSTREAM,		 "SpaceBank: Key %u has type %s, which is not the "		 "identification type (%s)\n",		 i,		 type_name(obType),		 type_name(type));      continue;    }        if (bank_containsOID(bank,type,oid)) {      retval &= ~(1u << i); /* mark success */    }    else DEBUG (dealloc) {      kdprintf(KR_OSTREAM, "Bank does not contain %s 0x"DW_HEX"\n",	       type_name(type),	       DW_HEX_ARG(oid));    }  }  return retval;}uint32_tbank_containsOID(Bank *bank, uint8_t type, OID oid){  struct Bank_MOFrame *obj_frame;  /* valid key slot */  uint64_t frameOff = EROS_FRAME_FROM_OID(oid);  uint8_t subObj = EROS_OBNDX_IN_FRAME(oid);  obj_frame = bank_getTypeFrame(bank, type);  if (obj_frame) {    if (obj_frame->frameMap != 0u && obj_frame->frameOid == frameOff) {      /* bit is set implies object is free */      return !(obj_frame->frameMap & (1<<subObj));    }  }    return allocTree_checkForOID(&bank->allocTree,oid);}uint32_tbank_deallocOID(Bank *bank, uint8_t type, OID oid){  struct Bank_MOFrame *obj_frame;  /* valid key slot */  uint64_t frameOff = EROS_FRAME_FROM_OID(oid);  uint8_t subObj = EROS_OBNDX_IN_FRAME(oid);  obj_frame = bank_getTypeFrame(bank, type);    if (obj_frame) {    if (obj_frame->frameMap != 0u && obj_frame->frameOid == frameOff) {      if (obj_frame->frameMap & (1<<subObj))	kpanic(KR_OSTREAM,		 "Spacebank: (frame)dealloc passed already "		 "unallocated object!\n");      obj_frame->frameMap |= (1<<subObj); /* mark free */      if (obj_frame->frameMap == objects_map_mask[type]) {	/* now the frame is empty -- return it */	uint32_t x;	DEBUG(dealloc)	  kprintf(KR_OSTREAM, "Returning empty %s frame\n",type_name(type));	for (x = 0; x < objects_per_frame[type]; x++) {	  allocTree_removeOID(&bank->allocTree,			      bank,			      type,			      obj_frame->frameOid | x);	  obj_frame->frameMap &= ~(1u << x);	}	/* no need to return the frame, as allocTree_removeOID takes	   care of all of that. */	obj_frame->frameOid = 0ull;      }      bank->deallocs[type]++;      return 1;    } /* if (obj_frame->frameMap != 0u && frameOid == frameOff) */      } /* if (obj_frame) ... */  /* not in the frame cache -- try the tree */  if (! allocTree_removeOID(&bank->allocTree, bank, type, oid) ) {    /* failed */    kprintf(KR_OSTREAM,	    "spacebank: oid 0x"DW_HEX" (%s) not in bank "	    "to dealloc\n",	    DW_HEX_ARG(oid),	    type_name(oid)	   );    return 0;  } else {    bank->deallocs[type]++;    return 1;  }}voidBankPreallType(Bank *bank,	       uint32_t type,	       uint64_t startOID,	       uint64_t number){  OID oid = startOID;  uint32_t residual;  uint32_t i;    uint32_t obPerFrame = objects_per_frame[type];  DEBUG(init)    kprintf(KR_OSTREAM,	    "Adding 0x%08x%08x %s\n",	    (uint32_t) (number>>32),	    (uint32_t) number,	    type_name(type));  residual = number;      for (i = 0; i < number; i += obPerFrame, oid += EROS_OBJECTS_PER_FRAME) {          uint32_t count = MIN(residual, obPerFrame);    OID top = oid + obPerFrame;    if (bank_ReserveFrames(bank, 1u) != RC_OK) {      kpanic(KR_OSTREAM,	     "SpaceBank: Hit limit while preallocating space!\n");    }    DEBUG(init)      kprintf(KR_OSTREAM,	       "Adding oids [0x"DW_HEX":0x"DW_HEX") resid %d count %d\n",	       DW_HEX_ARG(oid),	       DW_HEX_ARG(top),	       residual,	       count);        allocTree_insertOIDs(&bank->allocTree, type, oid, obPerFrame);    /* If last frame, set up residual in active alloc word     * Test can only be true if obPerFrame > 1.     */    if (count && count < obPerFrame) {      struct Bank_MOFrame *obj_frame;      uint32_t obMask;            /* get the type frame for the residual */      obj_frame = bank_getTypeFrame(bank, type);        if (!obj_frame) {	/* not a recognized multi-page object */	kpanic(KR_OSTREAM,	       "Spacebank: Fatal error: bank_preall_type got "	       "unsupported >1 per page type (%i)!\n",	       type);	       	break; /* BREAK */      }      if (obj_frame->frameMap != 0u) {	uint32_t x;		/* deallocate old stuff */	while (obj_frame->frameMap != 0u) {	  x = ffs(obj_frame->frameMap);	  allocTree_removeOID(&bank->allocTree,			      bank,			      type,			      obj_frame->frameOid | x);	  obj_frame->frameMap &= ~(1u << x);	}      }      obMask = (1u << obPerFrame) - 1;      obj_frame->frameOid = oid;      /* now mark the first /count/ objects allocated */      obj_frame->frameMap = ~( (1u << count) - 1 );      /* mask out the extraneous bits */      obj_frame->frameMap &= obMask;      DEBUG(init)	kdprintf(KR_OSTREAM,		 "Residual %s frame: oid=0x"DW_HEX" map: 0x%08x\n",		 type_name(type),		 DW_HEX_ARG(obj_frame->frameOid),		 obj_frame->frameMap);    }    residual -= count;  }  return;}static Bank *FreeBanks = 0;Bank *alloc_bank(void){  Bank *newBank;    if (FreeBanks) {    newBank = FreeBanks;    FreeBanks = *((Bank**) FreeBanks);  }  else    newBank = (Bank *) malloc(sizeof(Bank));  if (!newBank) return NULL;    bzero(newBank, sizeof(Bank*));  return newBank;}voidfree_bank(Bank * b){  *((Bank **)b) = FreeBanks;  FreeBanks = b;}

⌨️ 快捷键说明

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