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

📄 ck_restart.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1998, 1999, 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 <disk/DiskNode.hxx>#include <disk/PagePot.hxx>#include <kerninc/kernel.hxx>#include <kerninc/MsgLog.hxx>#include <kerninc/Checkpoint.hxx>#include <kerninc/Persist.hxx>#include <kerninc/ObjectCache.hxx>#include <kerninc/Thread.hxx>#include <kerninc/CpuReserve.hxx>#include <kerninc/Machine.hxx>#define dbg_ckdir	0x1	/* steps in ckdir reconstruction */#define dbg_reload	0x2	/* steps in reload */#define dbg_ckinit	0x4	/* steps in taking snapshot */#if 0#define dbg_ckpt	0x1	/* steps in taking snapshot */#define dbg_ckage	0x2	/* migration state machine */#define dbg_mig		0x4	/* migration state machine */#define dbg_reservation	0x40	/* reservation logic */#define dbg_wrckdir	0x80	/* writing ckdir */#define dbg_dirent	0x100	/* dirent manipulation */#define dbg_stabilize	0x200	/* stabilization */#define dbg_retag	0x400	/* stabilization */#endif/* Following should be an OR of some of the above */#define dbg_flags   (0u)#define DBCOND(x) (dbg_##x & dbg_flags)#define DEBUG(x) if DBCOND(x)#define DEBUG2(x,y) if ((dbg_##x|dbg_##y) & dbg_flags)static ThreadPile CheckpointedThreads;voidCheckpoint::Init(){  assert (EROS_NODES_PER_FRAME == DISK_NODES_PER_PAGE);    enabled = false;		/* until we know otherwise */    for (uint32_t i = 0; i < nThreadDirPage; i++) {    threadDirHdr[i] = 0;    threadDirPg[i] = 0;    lastThreadDirLid[i] = 0;    nextThreadDirLid[i] = 0;  }    for (uint32_t i = 0; i < nReserveDirPage; i++) {    reserveDirHdr[i] = 0;    reserveDirPg[i] = 0;    lastReserveDirLid[i] = 0;    nextReserveDirLid[i] = 0;  }  for (uint32_t i = 0; i < nGeneration; i++) {    coreGeneration[i].Init();    coreGeneration[i].index = i;    if (i > last_ckpt)      coreGeneration[i].canReclaim = true;  }  lastCkptHdr = 0;  nextCkptHdr = 0;  migrationStatus = mg_Idle;  nCheckpointsCompleted = 0;    CheckConsistency("Bottom Chekpoint::Init()", true);}voidCheckpoint::LoadDirectoryHeaders(){  /* These must be allocated by hand in order to get the correct log   * locations allocated.  The master checkpoint headers do not appear   * within the page allocations of the disk checkpoint areas.  They   * are not considered "available" for allocation.   */  AllocateMasterLid((lid_t)0);  AllocateMasterLid((lid_t)(1 * EROS_OBJECTS_PER_FRAME));  DEBUG(ckdir) MsgLog::printf("reading ckhdr 0\n");  lastCkptHdrLid = 0;  lastCkptObHdr = Persist::KernGetCkFrame(lastCkptHdrLid);  /* FIX: need to check for IO error.  Not sure how yet. */  assert(lastCkptObHdr);#if 1  lastCkptObHdr->Unintern();  lastCkptObHdr->obType = ObType::PtDriverPage; /* FIX: Race condition? */#else  lastCkptObHdr->KernPin();	/* forever... */#endif  lastCkptHdr = (DiskCheckpoint*) ObjectCache::ObHdrToPage(lastCkptObHdr);  DEBUG(ckdir) MsgLog::printf("0: pObj 0x%08x ppg 0x%08x, seqno 0x%x nThreadPg %d nDirPg %d\n",		 lastCkptObHdr,		 lastCkptHdr,		 (uint32_t) lastCkptHdr->sequenceNumber,		 (uint32_t) lastCkptHdr->nThreadPage,		 (uint32_t) lastCkptHdr->nDirPage);  /* In case ckhdr 1 is the current one, read that too: */    DEBUG(ckdir) MsgLog::printf("reading ckhdr 1\n");  nextCkptHdrLid = (lid_t)(1 * EROS_OBJECTS_PER_FRAME);  nextCkptObHdr = Persist::KernGetCkFrame(nextCkptHdrLid);  assert(nextCkptObHdr);  /* FIX: need to check for IO error.  Not sure how yet. */#if 1  nextCkptObHdr->Unintern();  nextCkptObHdr->obType = ObType::PtDriverPage; /* FIX: Race condition? */#else  nextCkptObHdr->KernPin();	/* forever... */#endif  nextCkptHdr = (DiskCheckpoint*) ObjectCache::ObHdrToPage(nextCkptObHdr);  DEBUG(ckdir) MsgLog::printf("1: pObj 0x%08x ppg 0x%08x, seqno 0x%x nThreadPg %d nDirPg %d\n",		 nextCkptObHdr,		 nextCkptHdr,		 (uint32_t) nextCkptHdr->sequenceNumber,		 (uint32_t) nextCkptHdr->nThreadPage,		 (uint32_t) nextCkptHdr->nDirPage);  /* Might have the headers swapped: */  if (nextCkptHdr->sequenceNumber == lastCkptHdr->sequenceNumber)    MsgLog::fatal("Cannot start: Checkpoint headers corrupted\n");  if (nextCkptHdr->sequenceNumber > lastCkptHdr->sequenceNumber)    SwapCheckpointHeaders();    CheckConsistency("bot Checkpoint::LoadDirHdrs", true);}/* Reserve pages are allocated from the checkpoint log just like * everything else, but they are allocated as master locations rather * than per-checkpoint locations. */voidCheckpoint::ReloadSavedReserves(){  DEBUG(reload) MsgLog::dprintf(true, "Reading %d saved reserve pages...\n",		 lastCkptHdr->nRsrvPage);  uint32_t entry = 0;    for (uint32_t i = 0; i < lastCkptHdr->nRsrvPage; i++, entry++) {    lid_t dirLid = lastCkptHdr->dirPage[entry];    AllocateMasterLid(dirLid);    lastReserveDirLid[i] = dirLid;        ObjectHeader *pObj = Persist::KernGetCkFrame(dirLid);    assert(pObj);#if 1    pObj->Unintern();    pObj->obType = ObType::PtDriverPage; /* FIX: Race condition? */#else    pObj->KernPin();	/* forever... */#endif    reserveDirHdr[i] = pObj;    ReserveDirPage *rdp = (ReserveDirPage *) ObjectCache::ObHdrToPage(pObj);    reserveDirPg[i] = rdp;    for (uint32_t ndx = 0; ndx < rdp->nDirent; ndx++) {      coreGeneration[last_ckpt].nReserve++;      CpuReserveInfo& ckrsrv = rdp->entry[ndx];      CpuReserve& rsrv = CpuReserve::CpuReserveTable[ckrsrv.index];      DEBUG(ckdir) if (ckrsrv.index < 5)	MsgLog::dprintf(true, "[%3d], dur 0x%08x%08x per 0x%08x%08x\n"			"quant 0x%08x%08x normPrio %d rsrvPrio %d\n",			ckrsrv.index,			(uint32_t) (ckrsrv.duration>>32),			(uint32_t) ckrsrv.duration,			(uint32_t) (ckrsrv.period>>32),			(uint32_t) ckrsrv.period,			(uint32_t) (ckrsrv.quanta>>32),			(uint32_t) ckrsrv.quanta,			ckrsrv.normPrio,			ckrsrv.rsrvPrio);      rsrv.residQuanta = 0;      rsrv.expired = true;      rsrv.residDuration = 0;      rsrv.active = false;      rsrv.quanta = ckrsrv.quanta;      rsrv.duration = ckrsrv.duration;      rsrv.period = ckrsrv.period;      rsrv.start = ckrsrv.start;      rsrv.normPrio = ckrsrv.normPrio;      rsrv.rsrvPrio = ckrsrv.rsrvPrio;      rsrv.Reset();    }  }  DEBUG(reload) MsgLog::dprintf(true, "Done reading reserves...\n");  CheckConsistency("bot Ckpt::ReloadSavedResources", true);}voidCheckpoint::ReloadSavedThreads(){  DEBUG(reload) MsgLog::dprintf(true, "Reading %d saved thread pages...\n",		 lastCkptHdr->nThreadPage);  uint32_t entry = lastCkptHdr->nRsrvPage;  for (uint32_t i = 0; i < lastCkptHdr->nThreadPage; i++, entry++) {    lid_t dirLid = lastCkptHdr->dirPage[entry];        AllocateMasterLid(dirLid);    lastThreadDirLid[i] = dirLid;        ObjectHeader *pObj = Persist::KernGetCkFrame(dirLid);    assert(pObj);#if 1    pObj->Unintern();    pObj->obType = ObType::PtDriverPage; /* FIX: Race condition? */#else    pObj->KernPin();	/* forever... */#endif    threadDirHdr[i] = pObj;        ThreadDirPage *tdp = (ThreadDirPage *) ObjectCache::ObHdrToPage(pObj);    threadDirPg[i] = tdp;    for (uint32_t ndx = 0; ndx < tdp->nDirent; ndx++) {      /* Fabricate a thread for each entry: */      coreGeneration[last_ckpt].nThread++;      ThreadDirent& tde = tdp->entry[ndx];      DEBUG(ckdir) MsgLog::dprintf(true, "Adding thread for OID 0x%08x%08x ac=%d\n",		      (uint32_t) (tde.oid>>32),		      (uint32_t) tde.oid,		      tde.allocCount);      /* FIX: What forged priority should we use (probably HIGH) --       * need to make sure that preparing a thread updates the       * priority field properly.       */            Thread* thread = new Thread;      assert(thread);      assert (thread->processKey.IsUnprepared());      assert( thread->processKey.IsHazard() == false );      /* Forge a domain key for this thread: */      Key& k = thread->processKey;      k.InitType(KT_Process);      k.unprep.oid = tde.oid;      k.unprep.count = tde.allocCount;      CpuReserve::CpuReserveTable[tde.schedNdx].AddUserThread(thread);      thread->SleepOn(CheckpointedThreads);    }  }  DEBUG(reload) MsgLog::dprintf(true, "All threads now on wakeup stall q\n");    CheckConsistency("bot Ckpt::ReloadSavedThreads()", true);}

⌨️ 快捷键说明

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