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

📄 kern_segment.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 2 页
字号:
	  return true;	}      case KT_Segment:      case KT_Node:#ifdef KT_Wrapper      case KT_Wrapper:#endif      case KT_Page:	{	  Node* segNode = 0;	  uint32_t parentBlss = wi.segBlss;	      	  wi.segBlss = wi.pSegKey->GetBlss();	  if (wi.segBlss > MAX_RED_BLSS)	    goto seg_malformed;	    	  /* This is NOT the same as the corresponding /if/ on many	   * systems -- the code generated by this expression contains	   * no branch.	   */	  wi.canWrite &= !wi.pSegKey->IsReadOnly();    	  wi.canFullFetch &= !wi.pSegKey->IsWeak();    	  if (!wi.canWrite && wi.writeAccess)	    goto access_fault;		  wi.canCall &= !wi.pSegKey->IsNoCall();		  wi.segObj = wi.pSegKey->ok.pObj;#ifdef KT_Wrapper	  wi.segObjIsWrapper = false;#else	  wi.segObjIsRed = false;#endif	  if ( keyType == KT_Node || keyType == KT_Segment ) {#ifndef KT_Wrapper	    if (wi.segBlss == EROS_PAGE_BLSS && wi.wantLeafNode) {	      WALK_DBG_MSG("lfnode")	      continue;	    }	    else if (wi.segBlss <= EROS_PAGE_BLSS &&		     wi.segBlss != BLSS::RedSeg)	      goto seg_malformed;#endif	    	    segNode = (Node *) wi.segObj;	  	    if (segNode->PrepAsSegment() == false)	      goto seg_thru_process;#ifndef KT_Wrapper	    if (wi.pSegKey->IsRedSegmentKey()) {	      pFormatKey = &segNode->slot[RedSegFormat];	      ADD_DEPEND(pFormatKey);	      /* FIX: Should we do a more general check to make sure that	       * reserved bits are set properly?  Probably..  grumble.	       */	  	      if (pFormatKey->IsType(KT_Number) == false)		goto seg_malformed;	      wi.segBlss = REDSEG_GET_BLSS(pFormatKey->nk);	      if (wi.segBlss > MAX_RED_BLSS)		goto seg_malformed;	      /* Note that we don't bother to extract the keeper key	       * location until we need it.	       */	      wi.segObjIsRed = true;	      wi.redSeg = segNode;	      wi.redSegOffset = wi.offset;	      wi.redSpanBlss = parentBlss - 1;	      WALK_DBG_MSG("redseg")	    }#endif	  }#ifdef KT_Wrapper	  else if ( keyType == KT_Wrapper ) {	    segNode = (Node *) wi.segObj;	  	    if (segNode->PrepAsSegment() == false)	      goto seg_malformed;	    pFormatKey = &segNode->slot[WrapperFormat];	    ADD_DEPEND(pFormatKey);	    wi.segBlss = WRAPPER_GET_BLSS(pFormatKey->nk);	    /* Note that we don't bother to extract the keeper key	     * location until we need it.	     */	    wi.segObjIsWrapper = true;	    wi.redSeg = segNode;	    wi.redSegOffset = wi.offset;	    wi.redSpanBlss = parentBlss - 1;	    WALK_DBG_MSG("wrapper")	  }#endif	  ADD_DEPEND(wi.pSegKey);	  /* Loop around again. */	  break;	}      case KT_Number:	wi.segBlss --; 	wi.segObj = 0;#ifdef KT_Wrapper	wi.segObjIsWrapper = false;#else	wi.segObjIsRed = false;#endif	/* FIX: When we implement window keys, may need to add depend	 * entries.	 */		switch(wi.pSegKey->nk.value[0] & 3) {	default:	  goto invalid_addr;	}	break;	      default:	goto seg_malformed;      }    }    /********************************     *      * END key processing logic:     *      ********************************/    /* Loop around again. */  } access_fault:  wi.faultCode = FC_Access;  goto fault_exit; invalid_addr:  wi.faultCode = FC_InvalidAddr;  goto fault_exit; bad_seg_depth:  wi.faultCode = FC_SegDepth;  goto fault_exit; seg_thru_process: seg_malformed:  wi.faultCode = FC_SegMalformed; fault_exit:  WALK_DBG_MSG("flt")  if (wi.invokeKeeperOK)    return p->InvokeSegmentKeeper(wi);  return false;}boolProcess::InvokeSegmentKeeper(SegWalk& wi){  Key *keeperKey = 0;  Key *pFormatKey = 0;  uint32_t keptBlss = 0;  bool sendNode = false;    if (wi.redSeg && wi.canCall) {    /* We know this key is valid or /wi.redSeg/ would not have been set. */#ifdef KT_Wrapper      assert(wi.redSeg->obType == ObType::NtSegment);      pFormatKey = &wi.redSeg->slot[WrapperFormat];      if (pFormatKey->nk.value[0] & WRAPPER_KEEPER)	keeperKey = &wi.redSeg->slot[WrapperKeeper];      keptBlss = WRAPPER_GET_BLSS(pFormatKey->nk);      sendNode = pFormatKey->nk.value[0] & WRAPPER_SEND_NODE;#else      pFormatKey = &wi.redSeg->slot[RedSegFormat];      uint32_t keeperSlot = REDSEG_GET_KPR_SLOT(pFormatKey->nk);      if (keeperSlot != RedSegFormat)	keeperKey = &wi.redSeg->slot[keeperSlot];      keptBlss = REDSEG_GET_BLSS(pFormatKey->nk);      sendNode = REDSEG_GET_SENDNODE(pFormatKey->nk);#endif    if (keeperKey && keeperKey->IsType(KT_Start) == false) {      /* THIS IS VALID, in the sense that it serves to suppress       * reporting to the process keeper.       */      keeperKey = &Key::VoidKey;    }  }    if (keeperKey == 0 && wi.invokeProcessKeeperOK == false)    return false;  /* Ensure retry on yield.  All segment faults are fast-path   * restartable.   */  SetFault(wi.faultCode, wi.vaddr, false);  if (keeperKey == 0) {    /* Yielding here will cause the thread to resume with a non-zero     * fault code in the scheduler, at which point it will be shunted     * off to the process keeper.     */    Thread::Current()->Yield();  }  assert(keeperKey);  /* If this was a memory fault, clear the PF_Faulted bit.  This   * allows us to restart the instruction properly without invoking   * the process keeper in the event that we are forced to yield in the   * middle of preparing the keeper key or calling InvokeMyKeeper;   */  processFlags &= ~PF_Faulted;    /* The only policy decision to make here is whether to pass a key   * argument.   */  Key *keyToPass = &Key::VoidKey;    if (sendNode) {    /* This could be a call driven by SetupExitString(), in which the     * original invocation was to a red segment key with the node     * passing option turned on, so do not reuse scratchKey.     */    inv.redNodeKey.InitType(KT_Node);    inv.redNodeKey.SetPrepared();    wi.redSeg->TransLock();    inv.redNodeKey.ok.pObj = wi.redSeg;    inv.redNodeKey.ok.next = wi.redSeg->kr.next;    inv.redNodeKey.ok.prev = (KeyRing*) wi.redSeg;    wi.redSeg->kr.next = (KeyRing *) &inv.redNodeKey;    inv.redNodeKey.ok.next->prev = (KeyRing*) &inv.redNodeKey;    inv.flags |= INV_REDNODEKEY;    keyToPass = &inv.redNodeKey;  }  /* NOTE DELICATE ISSUE   *    *   If the keeper is a resume key we must mark the containing   *   segment node dirty.  See the comments in kern_Invoke.cxx for an   *   explanation.   *    *   In practice, if you use a resume key in a keeper slot you are a   *   bogon anyway, so I'm not real worried about it...   *    *   The following may yield, but note that all segment faults are   *   restartable, so it's okay.  There is no need for a similar   *   check in InvokeProcessKeeper(), because process root is always   *   dirty.   */  if (keeperKey->IsType(KT_Resume))    wi.redSeg->MakeObjectDirty();#ifdef OPTION_DDB  if (ddb_segwalk_debug) {    static uint64_t last_offset = 0x0ll;    if (wi.redSegOffset != last_offset) {      dprintf(true, "Invoking segment keeper. redseg 0x%x"		      " base 0x%X last 0x%X\n",		      wi.redSeg, wi.redSegOffset, last_offset);      last_offset = wi.redSegOffset;    }  }#endif  InvokeMyKeeper(OC_SEGFAULT, wi.faultCode,		 (uint32_t) wi.redSegOffset, (uint32_t) (wi.redSegOffset>>32),		 keeperKey, keyToPass,		 0, 0);    /* NOTREACHED */  return false;}

⌨️ 快捷键说明

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