📄 kern_objectheader.cxx
字号:
voidObjectHeader::MakeObjectDirty(){ assertex(this, IsUserPinned()); assertex(this, GetFlags(OFLG_CURRENT)); if ( IsDirty() && (GetFlags(OFLG_CKPT|OFLG_IO) == 0) ) return; #ifndef NDEBUG extern bool InvocationCommitted;#endif assert (InvocationCommitted == false); if (obType == ObType::PtDataPage || obType == ObType::PtDevicePage || obType <= ObType::NtLAST_NODE_TYPE) assert(IsUserPinned()); FlushIfCkpt(); age = Age::NewBorn; #ifdef OPTION_OB_MOD_CHECK if (IsDirty() == 0 && ob.check != CalcCheck()) fatal("MakeObjectDirty(0x%08x): not dirty and bad checksum!\n", this);#endif#if 0 /* This was correct only because we were not reassigning new * locations every time an object was dirtied. Now that we are * doing reassignment, we must reregister. */ if (IsDirty()) { /* in case a write is in progress, mark reDirty, but must not do * this before registration unless we know the object is already * dirty. Note that we already know this object to be current! */ SetFlags(OFLG_REDIRTY); return; }#endif #ifdef OPTION_PERSISTENT Checkpoint::RegisterDirtyObject(this);#endif SetDirtyFlag(); ClearFlags(OFLG_CKPT); #if 0 /* FIX: Why should we ever do this here? */ ClearFlags(OFLG_REDIRTY);#endif#ifdef DBG_CLEAN dprintf(true, "Marked pObj=0x%08x oid=0x%08x%08x dirty. dirty: %c chk: %c\n", this, (uint32_t) (oid >> 32), (uint32_t) (oid), GetFlags(OFLG_DIRTY) ? 'y' : 'n', GetFlags(OFLG_CKPT) ? 'y' : 'n');#endif#ifdef DBG_WILD_PTR if (dbg_wild_ptr) Check::Consistency("Top RegisterDirtyObject()");#endif#if 0 uint32_t ocpl = IRQ::splhigh() printf("** Object "); print(oid); printf(" marked dirty.\n"); IRQ::splx(ocpl);#endif}voidObjectHeader::Rescind(){ DEBUG(rescind) dprintf(true, "Rescinding ot=%d oid=0x%08x%08x\n", obType, (uint32_t) (ob.oid >> 32), (uint32_t) ob.oid); assert (IsDirty() && GetFlags(OFLG_IO|OFLG_CKPT) == 0); assert (GetFlags(OFLG_CURRENT) == OFLG_CURRENT); #ifndef NDEBUG if (!kr.IsValid(this)) dprintf(true, "Keyring of oid 0x%08x%08x invalid!\n", (uint32_t)(ob.oid>>32), (uint32_t)ob.oid);#endif bool hasCaps = GetFlags(OFLG_DISKCAPS) ? true : false; kr.RescindAll(hasCaps); DEBUG(rescind) dprintf(true, "After 'RescindAll()'\n"); /* If object has on-disk keys, must dirty the new object to ensure * that it gets written. */ if (hasCaps) { ob.allocCount++; if (obType <= ObType::NtLAST_NODE_TYPE) ((Node *) this)->callCount++; ClearFlags(OFLG_DISKCAPS); DEBUG(rescind) dprintf(true, "After bump alloc count\n"); } /* FIX: Explicitly zeroing defeats the sever operation. */ if (obType <= ObType::NtLAST_NODE_TYPE) { /* zeroing unprepares and invalidates products too */ ((Node *) this)->DoClearThisNode(); assert ( obType == ObType::NtUnprepared ); } else if (obType == ObType::PtDataPage) { InvalidateProducts(); kva_t pPage = ObjectCache::ObHdrToPage(this); bzero((void*)pPage, EROS_PAGE_SIZE); } else if (obType == ObType::PtDevicePage) { fatal("Rescind of device pages not tested -- see shap!\n"); InvalidateProducts(); /* Do not explicitly zero device pages -- might be microcode! */ } else fatal("Rescind of non-object!\n"); DEBUG(rescind) dprintf(true, "After zero object\n");}voidObjectHeader::ZapResumeKeys(){ kr.ZapResumeKeys();}#ifdef OPTION_OB_MOD_CHECKuint32_tObjectHeader::CalcCheck() const{ uint32_t ck = 0; #ifndef NDEBUG uint8_t oflags = flags;#endif#if 0 printf("Calculating cksum for 0x%08x\n", this); printf("OID is 0x%08x%08x, ty %d\n", (uint32_t) (oid>>32), (uint32_t) oid, obType);#endif if (obType <= ObType::NtLAST_NODE_TYPE) { assert (ObjectCache::ValidNodePtr((Node *) this)); /* Object is a node - compute XOR including allocation count, call * counts, and key slots. */ Node *pNode = (Node *) this;#if 0 ck ^= ((uint32_t *) &allocCount)[0]; ck ^= ((uint32_t *) &allocCount)[1]; ck ^= ((uint32_t *) &(pNode->callCount))[0]; ck ^= ((uint32_t *) &(pNode->callCount))[1];#else ck ^= ob.allocCount; ck ^= pNode->callCount;#endif for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) ck ^= (*pNode)[i].CalcCheck(); } else { assert (ObjectCache::ValidPagePtr(this)); uint32_t *pageData = (uint32_t *) ObjectCache::ObHdrToPage(this); for (uint32_t w = 0; w < EROS_PAGE_SIZE/sizeof(uint32_t); w++) ck ^= pageData[w]; } assert(flags == oflags); return ck;}#endifvoidObjectHeader::InvalidateProducts(){ if (obType == ObType::PtDataPage || obType == ObType::PtDevicePage || obType == ObType::NtSegment) { /* We need to zap the product chain (MAJOR bummer!) */ while (products) { ObjectHeader *pProd = products; assert( pProd->obType == ObType::PtMappingPage ); products = products->next; Depend_InvalidateProduct(pProd); ObjectCache::ReleaseFrame(pProd); } products = 0; }}#ifdef OPTION_DDBvoidObjectHeader::ddb_dump(){ extern void db_printf(const char *fmt, ...);#ifdef OPTION_OB_MOD_CHECK printf("Object Header 0x%08x (%s) calcCheck 0x%08x:\n", this, ObType::ddb_name(obType), /* CalcCheck() */ 0); printf(" oid=0x%08x%08x ac=0x%08x check=0x%08x\n", (uint32_t) (ob.oid >> 32), (uint32_t) ob.oid, ob.allocCount, ob.check);#else printf("Object Header 0x%08x (%s) oid=0x%016X ac=0x%08x\n", this, ObType::ddb_name(obType), ob.oid, ob.allocCount);#endif printf(" ioCount=0x%08x next=0x%08x flags=0x%02x obType=0x%02x age=0x%02x\n", ob.ioCount, next, flags, obType, age); printf(" prodNdx=%d prodBlss=%d rwProd=%c usrPin=%d kernPin=%d\n", producerNdx, producerBlss, rwProduct ? 'y' : 'n', userPin, kernPin); switch(obType) { case ObType::PtMappingPage: printf(" producer=0x%08x\n", producer); break; case ObType::PtDataPage: case ObType::PtDevicePage: case ObType::NtSegment: { ObjectHeader *oh = products; printf(" products= ", products); while (oh) { printf(" 0x%08x", oh); oh = oh->next; } printf("\n", products); break; } case ObType::NtProcessRoot: case ObType::NtKeyRegs: case ObType::NtRegAnnex: printf(" context=0x%08x\n", context); break; } printf(" pageAddr=0x%08x\n", pageAddr);}#endif#ifdef KT_Wrapper/* #define PIN_DEBUG */#endif#ifndef NDEBUGvoidObjectHeader::TransLock() /* lock for current transaction */{#ifdef PIN_DEBUG printf("Pinning obhdr 0x%08x\n", this);#endif userPin = CurrentTransaction;}voidObjectHeader::TransUnlock(){#ifdef PIN_DEBUG printf("Un-pinning obhdr 0x%08x\n", this);#endif userPin = 0;}#endif#if 0voidObjectHeader::StartIO(){ SetFlags(OFLG_IO); ob.ioCount += 1; assert(ob.ioCount == 1);}voidObjectHeader::FinishObjectIO(bool isInbound, ObType::Type obType, OID oid, ObCount allocCount){#ifdef OPTION_OB_MOD_CHECK /* Recomputing does no harm even if the object is dirty, and is * necessary if the object is clean: */ ob.check = CalcCheck();#endif if (GetFlags(OFLG_REDIRTY)) assert(GetFlags(OFLG_DIRTY)); else { assert ( PTE::ObIsNotWritable(this) ); ClearFlags(OFLG_DIRTY); } ClearFlags(OFLG_IO|OFLG_REDIRTY); if (isInbound) { assert (obType == ObType::PtDriverPage); /* This was an incoming object. Set up the bits and intern it: */ SetFlags(OFLG_CURRENT|OFLG_DISKCAPS);#ifdef OFLG_PIN ClearFlags(OFLG_PIN);#endif products = 0; kr.ResetRing(); obType = obType; ob.oid = oid; ob.allocCount = allocCount; Intern(); } /* Wake up the programs sleeping for this object: */ ObjectSleepQueue().WakeAll(); ob.ioCount -= 1; assert(ob.ioCount == 0); ClearFlags(OFLG_IO);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -