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