blob: d43b64c7fe21698d033c2a2c9e44e2bede1ebe09 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#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);
}
|