📄 ck_restart.cxx
字号:
/* * 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 + -