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

📄 swaparea.cxx

📁 C++ 编写的EROS RTOS
💻 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 "kernel.hxx"#include "CheckPoint.hxx"#include "kernel/DiskNode.hxx"#include "SwapArea.hxx"#include "CoreDivision.hxx"#include "UserMem.hxx"SwapArea::SwapArea(uint32_t idx){  divOne = 0;  divTwo = 0;  status = Available;  availDirEnt = 0;  availNodeEnt = 0;  dirPageChain = 0;  curDirEntNdx = 0;  areaIndex = idx;    nextLoc = 0;  topLoc = 0;    int i;  for(i = 0; i < SWAP_DIR_HASH; i++)    dirPtr[SWAP_DIR_HASH] = 0;  for(i = 0; i < NUM_SLM_ROOT; i++)    slmRoots[i] = 0;}intSwapArea::findSwapDivisions(){  uint32_t cd;    if (!Persist::maxDiv())    return 0;    if (divOne && divOne->availSwapFrames() == 0)    divOne = 0;  if (divTwo && divTwo->availSwapFrames() == 0)    divTwo = 0;    if (!divOne) {	/* find first swap division - want the largest one. */        divOne = Persist::getcd(0);        for (cd = 0; cd < Persist::maxDiv(); cd++) {      CoreDivision *cur = Persist::getcd(cd);            if (cur->cdalo != areaIndex)	continue;            if (cur->availSwapFrames() > divOne->availSwapFrames())	divOne = cur;    }    	/* best may be empty - time to checkpoint! */    if (!divOne || !divOne->availSwapFrames()) {      divOne = 0;      return 0;    }        divTwo = 0;			/* new div1 means need new div2 */  }    if (!divTwo) {	/* find second swap division.  Want the smallest one not on the	 * same device as the first one.	 */    	/* First try the paranoid strategy: */    for (cd = 0; cd < Persist::maxDiv(); cd++) {      CoreDivision* cur = Persist::getcd(cd);            if (cur->cdalo != areaIndex)	continue;            if (cur->device != divOne->device &&	  cur->availSwapFrames()) {	if (!divTwo || cur->availSwapFrames() < divTwo->availSwapFrames())	  divTwo = cur;      }    }  }  #ifndef PARANOID_SWAP_ONLY      /* There may not be one.  Time to try the duplex strategy */  if (!divTwo) {    for (cd = 0; cd < Persist::maxDiv(); cd++) {      CoreDivision* cur = Persist::getcd(cd);            if (cur->cdalo != areaIndex)	continue;            if (cur->availSwapFrames()) {	if (!divTwo || cur->availSwapFrames() < divTwo->availSwapFrames())	  divTwo = cur;      }    }  }#endif    if (!divTwo) {    int count = 0;    	/* We now need to decide whether the return value is should be	 * bad or good.  If there is more than one swap division in	 * our generation, this is a bad search.	 */        for (cd = 0; cd < Persist::maxDiv(); cd++) {      CoreDivision* cur = Persist::getcd(cd);            if (cur->cdalo != areaIndex)	continue;    }        if (count > 1)      return 0;  }    return 1;}/* reset() - checkpoint of current area has completed.  This area was * migration area.  Reset it to make it the current area. */int SwapArea::canMutateNode(){      /* we can safely mutate a node if there is room in the current       * node pot and there is room in the directory.       */  if (!allocSwapDirent())    return 0;    if (availNodeEnt == 0) {    if (allocSwapFrame())      availNodeEnt = DISK_NODES_PER_PAGE;    else      return 0;  }  availNodeEnt--;  return 1;}int SwapArea::canMutatePage(CDA cda){      /* we can safely mutate a page if there is room in the current       * node pot and there is room in the directory.       */      /* it is also okay if we have already mutated this page.  In       * this case we know because we already have a CDA->swaploc       * mapping for it.       */  if (findPage(cda))    return 1;  if (!allocSwapDirent())    return 0;    return allocSwapFrame();}int SwapArea::allocSwapFrame(){  if (!findSwapDivisions())    return 0;    if (topLoc >= MAX_SWAPLOC)    return 0;  assert(divOne);      /* make sure we have a place to put the mapping we build: */    uint32_t slmRootNdx = topLoc / NUM_SLM_ROOT;  uint32_t slmChildNdx = topLoc % NUM_SLM_ROOT;  if (!slmRoots[slmRootNdx]) {    CoreObject *pgco = UserMem.grabPage();    if (!pgco)      return 0;    slmRoots[slmRootNdx] = (SwapLocMapping*) UserMem.CTEtoPage(pgco);  }  SwapLocMapping& slm = slmRoots[slmRootNdx][slmChildNdx];  slm.where[0].divNdx = divOne->divisionID;  slm.where[0].divFrame = divOne->nextSwapFrame++;    if (divTwo) {    slm.where[1].divNdx = divTwo->divisionID;    slm.where[1].divFrame = divTwo->nextSwapFrame++;  } else {    slm.where[1].divFrame = 0;	/* invalid value */  }    topLoc++;  return 1;}int SwapArea::allocSwapDirent(){      /* if we need to grow the on-disk directory, try to do so: */  if (availDirEnt == 0) {    if (allocSwapFrame())      availDirEnt = DIRENT_PER_PAGE;    else      return 0;  }  availDirEnt--;  return 1;}#if 0/* doAlloc() - allocate a new swap page frame. */int SwapArea::doAlloc(int numDirent){  assert(numDirent < DIRENT_PER_PAGE);    int pagesNeeded = 1;		/* for the node pot or data page */  if (nDirEnt + newDirent > DIRENT_PER_PAGE)    pagesNeeded ++;  if (freePages < pagesNeeded)    return 0;  freePages -= pagesNeeded;    nDirEnt += newDirent;    if (nDirEnt > DIRENT_PER_PAGE)    nDirEnt -= DIRENT_PER_PAGE;  return 1;}int SwapArea::allocNodePot(){  return doAlloc(DISK_NODES_PER_PAGE);}int SwapArea::allocPage(){  return doAlloc(1);}void SwapArea::init(CoreDivision* coreDiv){  cd = coreDiv; totPages = cd->nPages; clear();}#endif

⌨️ 快捷键说明

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