📄 vm_sched.c
字号:
/* * vm_sched.c */#ifndef lintstatic char *sccsid = "@(#)vm_sched.c 4.1 (ULTRIX) 7/2/90";#endif lint/************************************************************************ * * * Copyright (c) 1983,86 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * Modification History * * 14 Sep 88 -jaa * Took out swapping from sched() per RR. * Problem lies in pushing the UAREA and pte's * Once solved this MUST go back in (or at least revisited) * * 15 Dec 86 -- depp * Added fix to shared memory handling, in regards to a process' SM * page table swapping space. * * 29 Oct 86 -- jaw fix MP swapper bug. doing remrq without checking if * process is on the slave. * * 11 Sep 86 -- koehler * gnode name change * * 10-Jul-86 -- tresvik * moved lotsfree, desfree and minfree to param.c so that * the defaults could be overriden * * 02 Apr 86 -- depp * Changed method of calculating "lotsfree" so that paging will not * be turned on when there is plenty of memory. This was a problem * in large memory configurations. * * 16 Jul 85 -- jrs * Added run queue locking * * 11 Nov 85 -- depp * Removed all conditional compiles for System V. * * 30 Sept 85 -- depp * Added checks for memory locking * */#include "../h/param.h"#include "../h/systm.h"#include "../h/seg.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/proc.h"#include "../h/text.h"#include "../h/vm.h"#include "../h/cmap.h"#include "../h/kernel.h"#include "../h/interlock.h"#include "../h/cpudata.h"#ifdef mips#include "../h/fixpoint.h"#endif mipsint maxslp = MAXSLP;int saferss = SAFERSS;/* * The following parameters control operation of the page replacement * algorithm. They are initialized to 0, and then computed at boot time * based on the size of the system. If they are patched non-zero in * a loaded vmunix they are left alone and may thus be changed per system * using adb on the loaded system. */int maxpgio = 0;int slowscan = 0;int fastscan = 0;int klin = KLIN;int klseql = KLSEQL;int klsdist = KLSDIST;int kltxt = KLTXT;int klout = KLOUT;int multprog = -1; /* so we don't count process 2 */#ifdef vaxextern int minfree;extern int desfree;extern int lotsfree;#endif vax#ifdef mipsint minfree = 0;int desfree = 0;int lotsfree= 0;#endif mips#ifdef vaxdouble avenrun[3]; /* load average, of runnable procs */#endif vax#ifdef mipsfix avenrun[3]; /* load average, of runnable procs */#endif/* * Setup the paging constants for the clock algorithm. * Called after the system is initialized and the amount of memory * and number of paging devices is known. * * Threshold constants are defined in ../machine/vmparam.h. */setupclock(){#ifdef mips XPRINTF(XPR_VM,"enter setupclock",0,0,0,0);#endif mips /* * Setup thresholds for paging: * lotsfree is threshold where paging daemon turns on * desfree is amount of memory desired free. if less * than this for extended period, do swapping * minfree is minimal amount of free memory which is * tolerable. */ if (lotsfree == 0) lotsfree = LOTSFREE / NBPG; if (desfree == 0) { desfree = DESFREE / NBPG; if (desfree > LOOPPAGES / DESFREEFRACT) desfree = LOOPPAGES / DESFREEFRACT; } if (minfree == 0) { minfree = MINFREE / NBPG; if (minfree > desfree / MINFREEFRACT) minfree = desfree / MINFREEFRACT; } /* * Maxpgio thresholds how much paging is acceptable. * This figures that 2/3 busy on an arm is all that is * tolerable for paging. We assume one operation per disk rev. */ if (maxpgio == 0) maxpgio = (DISKRPM * 2) / 3; /* * Clock to scan using max of ~~10% of processor time for sampling, * this estimated to allow maximum of 200 samples per second. * This yields a ``fastscan'' of roughly (with CLSIZE=2): * <=1m 2m 3m 4m 8m * 5s 10s 15s 20s 40s *//* if (nswdev == 1 && physmem*NBPG > LOTSOFMEM*1024*(1024-16)) printf("WARNING: should run interleaved swap with >= %dMb\n", LOTSOFMEM);*/ if (fastscan == 0) fastscan = (LOOPPAGES/CLSIZE) / 200; if (fastscan < 5) fastscan = 5; if (nswdev >= 2) maxpgio = (maxpgio * 3) / 2; /* * Set slow scan time to 1/2 the fast scan time. */ if (slowscan == 0) slowscan = 2 * fastscan;}/* * The main loop of the scheduling (swapping) process. * * The basic idea is: * see if anyone wants to be swapped in; * swap out processes until there is room; * swap him in; * repeat. * If the paging rate is too high, or the average free memory * is very low, then we do not consider swapping anyone in, * but rather look for someone to swap out. * * The runout flag is set whenever someone is swapped out. * Sched sleeps on it awaiting work. * * Sched sleeps on runin whenever it cannot find enough * core (by swapping out or otherwise) to fit the * selected swapped process. It is awakened when the * core situation changes and in any case once per second. * * sched DOESN'T ACCOUNT FOR PAGE TABLE SIZE IN CALCULATIONS. */#define swappable(p) \ (((p)->p_flag&(SSYS|SLOCK|SULOCK|SLOAD|SPAGE|SKEEP|SWEXIT|SPHYSIO))==SLOAD)/* insure non-zero */#define nz(x) (x != 0 ? x : 1)#define NBIG 4#define MAXNBIG 10int nbig = NBIG;struct bigp { struct proc *bp_proc; int bp_pri; struct bigp *bp_link;} bigp[MAXNBIG], bplist;sched(){ register struct proc *rp, *p, *inp; int cpuindex,outpri, inpri, rppri; int sleeper, desperate, deservin, needs, divisor; register struct bigp *bp, *nbp; int biggot, gives;#ifdef mips XPRINTF(XPR_VM,"enter sched",0,0,0,0);#endif mipsloop: wantin = 0; deservin = 0; sleeper = 0; p = 0; /* * See if paging system is overloaded; if so swap someone out. * Conditions for hard outswap are: * if need kernel map (mix it up). * or * 1. if there are at least 2 runnable processes (on the average) * and 2. the paging rate is excessive or memory is now VERY low. * and 3. the short (5-second) and longer (30-second) average * memory is less than desirable. */ if (kmapwnt ||#ifdef vax (avenrun[0] >= 2 && imax(avefree, avefree30) < desfree &&#endif vax#ifdef mips (avenrun[0] >= TO_FIX(2) && imax(avefree, avefree30) < desfree &&#endif mips (rate.v_pgin + rate.v_pgout > maxpgio || avefree < minfree))) { desperate = 1; goto hardswap; } desperate = 0; /* * Not desperate for core, * look for someone who deserves to be brought in. */ outpri = -20000;#ifdef mips XPRINTF(XPR_VM,"sched searching for proc",0,0,0,0);#endif mips for (rp = allproc; rp != NULL; rp = rp->p_nxt) {#ifdef mips XPRINTF(XPR_VM,"pid = 0x% %d stat = 0x%x\n",rp,rp->p_pid,rp->p_stat,0);#endif mips switch(rp->p_stat) { case SRUN: if ((rp->p_flag&SLOAD) == 0) { rppri = rp->p_time - rp->p_swrss / nz((maxpgio/2) * (klin * CLSIZE)) + rp->p_slptime - (rp->p_nice-NZERO)*8; if (rppri > outpri) { if (rp->p_poip) continue; if (rp->p_textp && rp->p_textp->x_poip) continue; p = rp; outpri = rppri; } } continue; case SSLEEP: case SSTOP: if ((freemem < desfree || rp->p_rssize == 0) && rp->p_slptime > maxslp && (!rp->p_textp || (rp->p_textp->x_flag&(XLOCK|XNOSW))==0) && swappable(rp)) { /* * Kick out deadwood. */#ifndef ultrix#ifdef mips (void) splhigh();#endif mips#ifdef vax (void) spl6();#endif vax lock(LOCK_RQ); if (rp->p_stat == SRUN) { for (cpuindex = 0; cpuindex < activecpu; cpuindex++) { if (rp == cpudata[cpuindex].c_proc && cpudata[cpuindex].c_noproc == 0) { break; } } if (cpuindex < activecpu) { unlock(LOCK_RQ); (void) spl0(); continue; } else remrq(rp); }#endif !ultrix rp->p_flag &= ~SLOAD;#ifndef ultrix unlock(LOCK_RQ); (void) spl0();#endif !ultrix (void) swapout(rp, rp->p_dsize, rp->p_ssize, rp->p_smsize); /* SHMEM */#ifndef ultrix goto loop;#endif !ultrix } continue; } }#ifdef mips if(p) XPRINTF(XPR_VM,"found one p = 0x%x, pid = %d\n",p,p->p_pid,0,0);#endif mips /* * No one wants in, so nothing to do. */ if (outpri == -20000) {#ifdef mips (void) splhigh();#endif mips#ifdef vax (void) spl6();#endif vax if (wantin) { wantin = 0; sleep((caddr_t)&lbolt, PSWP); } else { runout++; sleep((caddr_t)&runout, PSWP); } (void) spl0(); goto loop; } /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -