diff options
Diffstat (limited to 'src/cmd/venti/srv/disksched.c')
-rw-r--r-- | src/cmd/venti/srv/disksched.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/cmd/venti/srv/disksched.c b/src/cmd/venti/srv/disksched.c new file mode 100644 index 00000000..687616e1 --- /dev/null +++ b/src/cmd/venti/srv/disksched.c @@ -0,0 +1,88 @@ +#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=%lux\n", getcallerpc(&level)); + return; + } + lasttime[level] = time(0); +} + |