Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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