| #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); |
| } |
| |