90 lines
2.1 KiB
C
90 lines
2.1 KiB
C
#include "stdinc.h"
|
|
#include "dat.h"
|
|
#include "fns.h"
|
|
|
|
ulong lasttime[2];
|
|
int manualscheduling;
|
|
int l0quantum = 120;
|
|
int l1quantum = 120;
|
|
ulong lasticachechange;
|
|
|
|
void
|
|
disksched(void)
|
|
{
|
|
int p, nwrite, nflush, ndirty, tdirty, toflush;
|
|
ulong t;
|
|
vlong cflush;
|
|
Stats *prev;
|
|
|
|
/*
|
|
* no locks because all the data accesses are atomic.
|
|
*/
|
|
t = time(0);
|
|
if(manualscheduling){
|
|
lasticachechange = t;
|
|
return;
|
|
}
|
|
|
|
if(t-lasttime[0] < l0quantum){
|
|
/* level-0 disk access going on */
|
|
p = icachedirtyfrac();
|
|
if(p < IcacheFrac*5/10){ /* can wait */
|
|
icachesleeptime = SleepForever;
|
|
lasticachechange = t;
|
|
}else if(p > IcacheFrac*9/10){ /* can't wait */
|
|
icachesleeptime = 0;
|
|
lasticachechange = t;
|
|
}else if(t-lasticachechange > 60){
|
|
/* have minute worth of data for current rate */
|
|
prev = &stathist[(stattime-60+nstathist)%nstathist];
|
|
|
|
/* # entries written to index cache */
|
|
nwrite = stats.n[StatIcacheWrite] - prev->n[StatIcacheWrite];
|
|
|
|
/* # dirty entries in index cache */
|
|
ndirty = stats.n[StatIcacheDirty] - prev->n[StatIcacheDirty];
|
|
|
|
/* # entries flushed to disk */
|
|
nflush = nwrite - ndirty;
|
|
|
|
/* want to stay around 70% dirty */
|
|
tdirty = (vlong)stats.n[StatIcacheSize]*700/1000;
|
|
|
|
/* assume nflush*icachesleeptime is a constant */
|
|
cflush = (vlong)nflush*(icachesleeptime+1);
|
|
|
|
/* computer number entries to write in next minute */
|
|
toflush = nwrite + (stats.n[StatIcacheDirty] - tdirty);
|
|
|
|
/* schedule for that many */
|
|
if(toflush <= 0 || cflush/toflush > 100000)
|
|
icachesleeptime = SleepForever;
|
|
else
|
|
icachesleeptime = cflush/toflush;
|
|
}
|
|
arenasumsleeptime = SleepForever;
|
|
return;
|
|
}
|
|
if(t-lasttime[1] < l1quantum){
|
|
/* level-1 disk access (icache flush) going on */
|
|
icachesleeptime = 0;
|
|
arenasumsleeptime = SleepForever;
|
|
return;
|
|
}
|
|
/* no disk access going on - no holds barred*/
|
|
icachesleeptime = 0;
|
|
arenasumsleeptime = 0;
|
|
}
|
|
|
|
void
|
|
diskaccess(int level)
|
|
{
|
|
if(level < 0 || level >= nelem(lasttime)){
|
|
fprint(2, "bad level in diskaccess; caller=%#p\n",
|
|
getcallerpc(&level));
|
|
return;
|
|
}
|
|
lasttime[level] = time(0);
|
|
}
|
|
|