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

📄 kern_objectheader.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1998, 1999, 2001, Jonathan S. Shapiro. * * 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 <kerninc/kernel.hxx>#include <kerninc/Check.hxx>#include <kerninc/ObjectHeader.hxx>#include <kerninc/ObjectCache.hxx>#include <kerninc/Thread.hxx>#include <kerninc/SegWalk.hxx>#include <kerninc/Depend.hxx>#include <arch-kerninc/PTE.hxx>#include <eros/memory.h>#define dbg_rescind	0x1	/* steps in taking snapshot *//* Following should be an OR of some of the above */#define dbg_flags   (0)#define DBCOND(x) (dbg_##x & dbg_flags)#define DEBUG(x) if DBCOND(x)#define DEBUG2(x,y) if ((dbg_##x|dbg_##y) & dbg_flags)/* If MAX_PIN is changed, may need to check for overflow on user * thread invocation of Pin(). */uint8_t ObjectHeader::CurrentTransaction = 1; /* guarantee nonzero! */#ifdef OPTION_DDBconst char *ObType::ddb_name(uint8_t t){  const char * names[] = {    "NtUnprep  ",    "NtSegment ",    "NtProcRoot",    "NtKeyRegs ",    "NtRegAnnex",    "NtFreeFrm ",    "PtDataPage",    "PtNewAlloc",    "PtKernHeap",#ifdef USES_MAPPING_PAGES    "PtMapPage ",#endif    "PtDevPage ",    "PtFreeFrm ",    0  };  return names[t];}#endifvoidObjectHeader::KernPin(){  assert(kernPin < BYTE_MAX);  kernPin++;#ifdef OFLG_PIN  SetFlags(OFLG_PIN);#endif}voidObjectHeader::KernUnpin(){  assert(kernPin);  kernPin--;#ifdef OFLG_PIN  if (kernPin == 0 && userPin == 0)    ClearFlags(OFLG_PIN);#endif}/* Walk the node looking for an acceptable product: */ObjectHeader *ObjectHeader::FindProduct(SegWalk& wi, uint32_t ndx, bool rw, bool ca){  uint32_t blss = wi.segBlss;#if 0  printf("Search for product blss=%d ndx=%d, rw=%c producerTy=%d\n",	       blss, ndx, rw ? 'y' : 'n', obType);#endif    /* #define FINDPRODUCT_VERBOSE */  ObjectHeader *product = 0;    for (product = products; product; product = product->next) {    if ((uint32_t) product->producerBlss != blss) {#ifdef FINDPRODUCT_VERBOSE      printf("Producer BLSS not match\n");#endif      continue;    }    if (product->mp.redSeg != wi.redSeg) {#ifdef FINDPRODUCT_VERBOSE      printf("Red seg not match\n");#endif      continue;    }    if (product->mp.redSeg) {#ifdef KT_Wrapper      if (product->mp.wrapperProducer != wi.segObjIsWrapper) {#ifdef FINDPRODUCT_VERBOSE	printf("redProducer not match\n"); #endif	continue;      }#else      if (product->mp.redProducer != wi.segObjIsRed) {#ifdef FINDPRODUCT_VERBOSE	printf("redProducer not match\n"); #endif	continue;      }#endif      if (product->mp.redSpanBlss != wi.redSpanBlss) {#ifdef FINDPRODUCT_VERBOSE	printf("redSpanBlss not match: prod %d wi %d\n",		       product->mp.redSpanBlss, wi.redSpanBlss);#endif	continue;      }    }    if ((uint32_t) product->producerNdx != ndx) {#ifdef FINDPRODUCT_VERBOSE      printf("producerNdx not match\n");#endif      continue;    }    if (product->rwProduct != (rw ? 1 : 0)) {#ifdef FINDPRODUCT_VERBOSE      printf("rwProduct not match\n");#endif      continue;    }    if (product->caProduct != (ca ? 1 : 0)) {#ifdef FINDPRODUCT_VERBOSE      printf("caProduct not match\n");#endif      continue;    }    /* WE WIN! */    break;  }  if (product) {    assert(product->producer == this);    assert(product->obType == ObType::PtMappingPage);  }#if 0  if (wi.segBlss != wi.pSegKey->GetBlss())    dprintf(true, "Found product 0x%x segBlss %d prodKey 0x%x keyBlss %d\n",		    product, wi.segBlss, wi.pSegKey, wi.pSegKey->GetBlss());#endif#ifdef FINDPRODUCT_VERBOSE  printf("0x%08x->FindProduct(blss=%d,ndx=%d,rw=%c,ca=%c,"		 "producerTy=%d) => 0x%08x\n",		 this,		 blss, ndx, rw ? 'y' : 'n', ca ? 'y' : 'n', obType,		 product);#endif  return product;}voidObjectHeader::AddProduct(ObjectHeader* product){  product->next = products;  product->producer = this;  products = product;}voidObjectHeader::DelProduct(ObjectHeader* product){  assert (product->producer == this);    if (products == product) {    products = product->next;  }  else {    ObjectHeader *curProd = products;    while (curProd->next) {      if (curProd->next == product) {	curProd->next = product->next;	break;      }      curProd = curProd->next;    }  }  product->next = 0;  product->producer = 0;}#if 0voidObjectHeader::DoCopyOnWrite(){  assert (obType > ObType::NtLAST_NODE_TYPE);#if 0  dprintf(true,		  "Trying copy on write, ty %d oid 0x%08x%08x "		  "hdr 0x%08x\n",		  obType, (uint32_t) (oid >> 32), (uint32_t) (oid), this);#endif  assert(GetFlags(OFLG_CKPT) && IsDirty());    ObjectHeader *pObj = ObjectCache::GrabPageFrame();  assert (pObj->kr.IsEmpty());  kva_t from = ObjectCache::ObHdrToPage(this);  kva_t to = ObjectCache::ObHdrToPage(pObj);      /* Copy the page data */  bcopy((const void *)from, (void *)to, EROS_PAGE_SIZE);  /* FIX -- the header needs to be copied with care -- perhaps this   * should be expanded in more explicit form?   */    /* And the object header: */  bcopy(this, pObj, sizeof(ObjectHeader));  /* The key ring needs to be reset following the header bcopy */  pObj->kr.ResetRing();    /* Because the original may already be queued up for I/O, the copy   * has to become the new version.  This poses a problem: we may have   * gotten here trying to mark an object dirty to satisfy a write   * fault, in which event there are very likely outstanding prepared   * capabilities to this object sitting on the stack somewhere.  In   * all such cases the object being copied will be pinned.  If the   * object being copied is pinned we Yield(), which will force the   * whole chain of events to be re-executed, this time arriving at   * the correct object.   */    /* NOTE About the 'dirty' bit -- which I have 'fixed' twice now to   * my regret.  It really should be zero.  We are only running this   * code if the object was marked ckpt.  In that event, the   * checkpointed version of the object is dirty until flushed, but   * the COW'd version of the object is not dirty w.r.t the next   * checkpoint until something happens along to try and dirty it.  We   * are here because someone is trying to do that, but we must let   * MakeObjectDirty() handle the marking rather than do it here.  The   * prolem is that we haven't reserved a directory entry for the   * object.  This can (and probably should) be resolved by calling   * RegisterDirtyObject() from here to avoid the extra Yield(), but   * for now be lazy, since I know that will actually work.   */    assert(kernPin == 0);    ClearFlags(OFLG_CURRENT);  pObj->SetFlags(OFLG_CURRENT);  pObj->ClearFlags(OFLG_CKPT|OFLG_IO|OFLG_DIRTY|OFLG_REDIRTY|OFLG_PIN);#ifdef DBG_CLEAN  printf("Object 0x%08x ty %d oid=0x%08x%08x COW copy cleaned\n",		 pObj, pObj->obType,		 (uint32_t) (pObj->oid >> 32),		 (uint32_t) pObj->oid);#endif  pObj->SetFlags(GetFlags(OFLG_DISKCAPS));  pObj->ioCount = 0;  pObj->userPin = 0;  pObj->prstPin = 0;#ifdef OPTION_OB_MOD_CHECK  pObj->check = pObj->CalcCheck();#endif  /* Switch the keyring to the new object, and update all of the keys   * to point to the copy:   */  kr.ObjectMoved(pObj);  Unintern();			/* take us out of the hash chain */  pObj->Intern();		/* and put the copy in in our place. */    /* we must now re-insert the old page as a log page, because the new   * page might conceivably get aged out before the old page, at which   * point we would find the wrong one.   */  #ifdef DBG_WILD_PTR  if (dbg_wild_ptr)    Check::Consistency("Bottom DoCopyOnWrite()");#endif  /* Since we may have come here by way of the page fault code, we are   * now forced to Yield(), because there are almost certainly   * outstanding pointers to this object on the stack:   */  Thread::Current()->Yield();}#endifvoidObjectHeader::FlushIfCkpt(){#ifdef OPTION_PERSISTENT#error "This needs an implementation."  /* If this page is involved in checkpointing, run the COW logic. */  if (GetFlags(OFLG_CKPT) && IsDirty()) {    assert (IsFree() == false);    if (obType <= ObType::NtLAST_NODE_TYPE) {      Checkpoint::WriteNodeToLog((Node *) this);      assert (!IsDirty());    }    else        Persist::WritePage(this, true);  }#else  assert(!GetFlags(OFLG_CKPT));#endif}

⌨️ 快捷键说明

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