|
|
1.1 root 1: /*
2: ** Share scheduler
3: */
4:
5: #include "sys/param.h"
6: #include "sys/lnode.h"
7: #include "sys/share.h"
8: #include "sys/charges.h"
9:
10:
11: float zerof = 0.0;
12: float onef = 1.0;
13: float twof = 2.0;
14:
15: static void adjgroups();
16:
17:
18:
19: /*
20: ** Assumes that a group parent has been inserted into list before any group member.
21: ** List is rooted in ``lnodes[0]''.
22: */
23:
24: share()
25: {
26: register KL_p lp;
27: register float maxusage;
28: register float f;
29: register float g;
30: register float h;
31: register float one = onef;
32:
33: Users = 1;
34: Groups = 0;
35: TotUsage = zerof;
36: MaxUsage = one;
37:
38: /*
39: ** Special treatment for root.
40: */
41:
42: lp = &lnodes[0];
43: f = lp->kl_cost;
44: lp->kl_cost = 0;
45: lp->kl.l_charge += f;
46: lp->kl_temp += f; /* Root's node accumulates all charges here */
47: lp->kl_usage = one; /* Root is not shared */
48:
49: if ( Shareflags & NOSHARE )
50: return;
51:
52: /*
53: ** Scan up active list and accumulate charges.
54: */
55:
56: for ( lp = lastlnode ; lp->kl_prev != (KL_p)0 ; lp = lp->kl_prev )
57: {
58: lp->kl_cost += lp->kl_muse * shconsts.sc_click; /* Charge for memory */
59: shconsts.sc_clickc += lp->kl_muse; /* Count memory click */
60: lp->kl_temp += lp->kl_cost;
61: lp->kl.l_charge += lp->kl_temp;
62: lp->kl_parent->kl_temp += lp->kl_temp;
63: }
64:
65: /*
66: ** Adjust costs for groups that are receiving too small a share.
67: */
68:
69: if ( Shareflags & ADJGROUPS )
70: adjgroups(lnodes, one, 0);
71:
72: /*
73: ** Scan down active list and process usage.
74: */
75:
76: maxusage = one;
77:
78: for ( lp = &lnodes[0] ; (lp = lp->kl_next) != (KL_p)0 ; )
79: {
80: if ( lp->kl_ghead != (KL_p)0 )
81: Groups++;
82: if ( !(lp->kl.l_flags & NOTSHARED) )
83: Users++;
84:
85: /*
86: ** Accumulate usage.
87: */
88:
89: f = lp->kl.l_usage;
90:
91: f *= DecayUsage;
92:
93: if ( lp->kl_ghead == (KL_p)0 )
94: f += lp->kl_temp;
95: else
96: f += lp->kl_cost;
97:
98: lp->kl.l_usage = f;
99:
100: if ( g = lp->kl_norms )
101: {
102: if ( (f /= g) < twof )
103: f = twof; /* The minimum */
104:
105: lp->kl_usage = f;
106:
107: if ( f > maxusage && f < MAXUSAGE )
108: maxusage = f;
109:
110: TotUsage += one / f;
111: }
112: else
113: lp->kl_usage = MAXUSAGE;
114:
115: lp->kl_temp = zerof;
116: lp->kl_cost = 0;
117: }
118:
119: MaxUsage = maxusage; /* Export value */
120:
121: /*
122: ** Limit kl_usage so that no user has more than MAXUSHARE * <allocated share>.
123: */
124:
125: if ( !(Shareflags & LIMSHARE) || TotUsage == zerof )
126: return;
127:
128: g = one / MAXUSHARE;
129:
130: for ( lp = &lnodes[0] ; (lp = lp->kl_next) != (KL_p)0 ; )
131: if
132: (
133: (h = lp->kl_usage) < maxusage
134: &&
135: (f = g / (TotUsage * lp->kl_eshare)) > h
136: &&
137: f < maxusage
138: )
139: {
140: TotUsage -= one / h;
141: f = g / lp->kl_eshare - one;
142: f /= TotUsage;
143: lp->kl_usage = f;
144: TotUsage += one / f;
145:
146: if ( f > maxusage && f < MAXUSAGE )
147: maxusage = f;
148: }
149:
150: MaxUsage = maxusage; /* Export value */
151: }
152:
153:
154:
155: /*
156: ** Increase run rates for groups getting more than their share.
157: */
158:
159: static void
160: adjgroups(gl, aa, d)
161: KL_p gl;
162: float aa;
163: int d;
164: {
165: register KL_p lp;
166: register float f;
167: register float totcharges = zerof;
168: register float a = aa;
169:
170: for ( lp = gl->kl_ghead ; lp != (KL_p)0 ; lp = lp->kl_gnext )
171: totcharges += lp->kl_temp;
172:
173: if ( (totcharges /= gl->kl_eshare * MINGSHARE) == zerof )
174: totcharges = onef;
175:
176: for ( lp = gl->kl_ghead ; lp != (KL_p)0 ; lp = lp->kl_gnext )
177: {
178: if ( lp->kl_ghead == (KL_p)0 || lp->kl_eshare == zerof )
179: {
180: lp->kl_rate *= a;
181: continue;
182: }
183:
184: if ( (f = lp->kl_temp / (lp->kl_eshare * totcharges)) > onef )
185: f *= a;
186: else
187: f = a;
188:
189: lp->kl_rate *= f;
190:
191: if ( d < MAXGROUPS )
192: adjgroups(lp, f, d+1);
193: }
194: }
195:
196:
197:
198: /*
199: ** Decay run rate.
200: */
201:
202: decayrate()
203: {
204: register KL_p lp = lnodes;
205: register float min = onef - NiceRates[NZERO];
206: register float dr = DecayRate;
207:
208: do
209: {
210: if ( (lp->kl_rate *= dr) < min )
211: lp->kl_rate = min;
212: }
213: while
214: ( (lp = lp->kl_next) != (KL_p)0 );
215: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.