1368c31abSDavid du Colombier #include "stdinc.h" 2368c31abSDavid du Colombier #include "dat.h" 3368c31abSDavid du Colombier #include "fns.h" 4368c31abSDavid du Colombier 5368c31abSDavid du Colombier ulong lasttime[2]; 6368c31abSDavid du Colombier int manualscheduling; 7368c31abSDavid du Colombier int l0quantum = 120; 8368c31abSDavid du Colombier int l1quantum = 120; 9368c31abSDavid du Colombier ulong lasticachechange; 10368c31abSDavid du Colombier 11368c31abSDavid du Colombier void disksched(void)12368c31abSDavid du Colombierdisksched(void) 13368c31abSDavid du Colombier { 14368c31abSDavid du Colombier int p, nwrite, nflush, ndirty, tdirty, toflush; 15368c31abSDavid du Colombier ulong t; 16368c31abSDavid du Colombier vlong cflush; 17368c31abSDavid du Colombier Stats *prev; 18368c31abSDavid du Colombier 19368c31abSDavid du Colombier /* 20368c31abSDavid du Colombier * no locks because all the data accesses are atomic. 21368c31abSDavid du Colombier */ 22368c31abSDavid du Colombier t = time(0); 23368c31abSDavid du Colombier if(manualscheduling){ 24368c31abSDavid du Colombier lasticachechange = t; 25368c31abSDavid du Colombier return; 26368c31abSDavid du Colombier } 27368c31abSDavid du Colombier 28368c31abSDavid du Colombier if(t-lasttime[0] < l0quantum){ 29368c31abSDavid du Colombier /* level-0 disk access going on */ 30368c31abSDavid du Colombier p = icachedirtyfrac(); 31368c31abSDavid du Colombier if(p < IcacheFrac*5/10){ /* can wait */ 32368c31abSDavid du Colombier icachesleeptime = SleepForever; 33368c31abSDavid du Colombier lasticachechange = t; 34368c31abSDavid du Colombier }else if(p > IcacheFrac*9/10){ /* can't wait */ 35368c31abSDavid du Colombier icachesleeptime = 0; 36368c31abSDavid du Colombier lasticachechange = t; 37368c31abSDavid du Colombier }else if(t-lasticachechange > 60){ 38368c31abSDavid du Colombier /* have minute worth of data for current rate */ 39368c31abSDavid du Colombier prev = &stathist[(stattime-60+nstathist)%nstathist]; 40368c31abSDavid du Colombier 41368c31abSDavid du Colombier /* # entries written to index cache */ 42368c31abSDavid du Colombier nwrite = stats.n[StatIcacheWrite] - prev->n[StatIcacheWrite]; 43368c31abSDavid du Colombier 44368c31abSDavid du Colombier /* # dirty entries in index cache */ 45368c31abSDavid du Colombier ndirty = stats.n[StatIcacheDirty] - prev->n[StatIcacheDirty]; 46368c31abSDavid du Colombier 47368c31abSDavid du Colombier /* # entries flushed to disk */ 48368c31abSDavid du Colombier nflush = nwrite - ndirty; 49368c31abSDavid du Colombier 50368c31abSDavid du Colombier /* want to stay around 70% dirty */ 51368c31abSDavid du Colombier tdirty = (vlong)stats.n[StatIcacheSize]*700/1000; 52368c31abSDavid du Colombier 53368c31abSDavid du Colombier /* assume nflush*icachesleeptime is a constant */ 54368c31abSDavid du Colombier cflush = (vlong)nflush*(icachesleeptime+1); 55368c31abSDavid du Colombier 56368c31abSDavid du Colombier /* computer number entries to write in next minute */ 57368c31abSDavid du Colombier toflush = nwrite + (stats.n[StatIcacheDirty] - tdirty); 58368c31abSDavid du Colombier 59368c31abSDavid du Colombier /* schedule for that many */ 60368c31abSDavid du Colombier if(toflush <= 0 || cflush/toflush > 100000) 61368c31abSDavid du Colombier icachesleeptime = SleepForever; 62368c31abSDavid du Colombier else 63368c31abSDavid du Colombier icachesleeptime = cflush/toflush; 64368c31abSDavid du Colombier } 65368c31abSDavid du Colombier arenasumsleeptime = SleepForever; 66368c31abSDavid du Colombier return; 67368c31abSDavid du Colombier } 68368c31abSDavid du Colombier if(t-lasttime[1] < l1quantum){ 69368c31abSDavid du Colombier /* level-1 disk access (icache flush) going on */ 70368c31abSDavid du Colombier icachesleeptime = 0; 71368c31abSDavid du Colombier arenasumsleeptime = SleepForever; 72368c31abSDavid du Colombier return; 73368c31abSDavid du Colombier } 74368c31abSDavid du Colombier /* no disk access going on - no holds barred*/ 75368c31abSDavid du Colombier icachesleeptime = 0; 76368c31abSDavid du Colombier arenasumsleeptime = 0; 77368c31abSDavid du Colombier } 78368c31abSDavid du Colombier 79368c31abSDavid du Colombier void diskaccess(int level)80368c31abSDavid du Colombierdiskaccess(int level) 81368c31abSDavid du Colombier { 82368c31abSDavid du Colombier if(level < 0 || level >= nelem(lasttime)){ 83*1f9fb570SDavid du Colombier fprint(2, "bad level in diskaccess; caller=%#p\n", 84*1f9fb570SDavid du Colombier getcallerpc(&level)); 85368c31abSDavid du Colombier return; 86368c31abSDavid du Colombier } 87368c31abSDavid du Colombier lasttime[level] = time(0); 88368c31abSDavid du Colombier } 89368c31abSDavid du Colombier 90