|
|
1.1 root 1: /*
2: ** Command to change/print costs for Share Scheduling Algorithm
3: */
4:
5: char * Usage =
6: "Usage: %s [-C] [-D<normal half-life secs>,<maxnice half-life secs>]\\\n\
7: [-E<rate half-life secs>] [-F<octal flags>] [-K<half-life>]\\\n\
8: [-P<maxpri>] [-Q<maxupri>] [-R<delta>] [-S<maxusers>]\\\n\
9: [-U<maxusage>] [-X<maxushare>] [-Y<mingshare>]\\\n\
10: [-b<bio>] [-m<click>] [-s<syscall>] [-t<tic>] [-y<tio>] [%%]\n";
11:
12: char * ShowUsage = "Usage: %s [-[v]]\n";
13:
14:
15: #include <sys/types.h>
16: #include <sys/lnode.h>
17: #include <sys/share.h>
18: #include <sys/charges.h>
19: #include <stdio.h>
20: #include <trace.h>
21: #include <math.h>
22: #include <libc.h>
23:
24:
25: char * Charges = "charges";
26: char * Name;
27: long Oldtick;
28: float Onef = 1.0;
29: float Oneh = 100.0;
30: float Percent = 100.0;
31: int Traceflag;
32: int Verbose;
33:
34: char Unk[] = "<unknown>";
35: char * Flags[16] =
36: {
37: "NOSHARE",
38: "ADJGROUPS",
39: "LIMSHARE",
40: Unk,
41: Unk,
42: Unk,
43: Unk,
44: Unk,
45: Unk,
46: Unk,
47: Unk,
48: Unk,
49: Unk,
50: Unk,
51: Unk,
52: Unk
53: };
54:
55: void error(), getcosts(), printcharges();
56:
57: #define NULLSTR (char *)0
58: #define STREQUAL 0
59: #define SYSERROR (-1)
60:
61: #ifdef EBUG
62: #define DEBUG EBUG /* for tests */
63: #define DODEBUG(A) A
64: #else
65: #define DODEBUG(A)
66: #endif EBUG
67:
68:
69:
70:
71:
72: main(argc, argv)
73: register int argc;
74: register char * argv[];
75: {
76: register long n;
77: register float f;
78: register char * cp;
79: register long newdecay = 0;
80: register long pdecay1 = 0;
81: register long pdecay2 = 0;
82: register long rdecay = 0;
83: extern char _sobuf[];
84:
85: if ( (Name = strrchr(*argv, '/')) != NULLSTR )
86: Name++;
87: else
88: Name = *argv;
89: argv++;
90: argc--;
91:
92: Oldtick = shconsts.sc_tick;
93:
94: if ( strcmp(Name, Charges) == STREQUAL )
95: {
96: Usage = ShowUsage;
97: (void)setbuf(stdout, _sobuf);
98:
99: if ( argc == 1 && strcmp(argv[0], "-") == STREQUAL )
100: {
101: Verbose = 1;
102: printcharges(1);
103: return 0;
104: }
105:
106: getcosts();
107: }
108:
109: while ( argc > 0 )
110: {
111: int seconds;
112:
113: if ( argv[0][0] != '\0' )
114: {
115: n = atol(&argv[0][1]);
116: f = atof(&argv[0][1]);
117:
118: if ( strchr(&argv[0][1], 's') != NULLSTR )
119: seconds = 1;
120: else
121: seconds = 0;
122: }
123:
124: switch ( argv[0][0] )
125: {
126: case '\0': break;
127: case '-': argv[0]++;
128: continue;
129: case 'C': getcosts();
130: break;
131: case 'D': if ( (cp = strchr(&argv[0][1], ',')) == NULLSTR )
132: error("Priority decay specification requires a range of half-lives\n");
133: pdecay1 = n;
134: pdecay2 = atol(cp+1);
135: if ( pdecay1 >= pdecay2 )
136: error("The decay half-life for maxnice processs should be less than that for normal processes");
137: break;
138: case 'E': rdecay = n;
139: break;
140: case 'F': Shareflags = atoo(&argv[0][1]);
141: break;
142: case 'G': MAXGROUPS = n;
143: break;
144: case 'K': newdecay = n;
145: if ( !seconds )
146: newdecay *= 60 * 60;
147: break;
148: case 'P': MAXPRI = f;
149: break;
150: case 'Q': MAXUPRI = f;
151: break;
152: case 'R': Delta = n;
153: break;
154: case 'S': MAXUSERS = n;
155: break;
156: case 'T': Traceflag = n?n:1;
157: break;
158: case 'U': MAXUSAGE = f;
159: break;
160: case 'X': MAXUSHARE = f;
161: break;
162: case 'Y': MINGSHARE = f;
163: break;
164: case 'b': shconsts.sc_bio = f;
165: break;
166: case 'm': shconsts.sc_click = f;
167: break;
168: case 's': shconsts.sc_syscall = f;
169: break;
170: case 't': shconsts.sc_tick = f;
171: break;
172: case 'v': Verbose = 1;
173: break;
174: case 'y': shconsts.sc_tio = f;
175: break;
176: default: if ( (n = atol(argv[0])) > 0 )
177: {
178: Percent = n;
179: break;
180: }
181: error("unrecognised argument %s", argv[0]);
182: case '?': fprintf(stderr, Usage, Name);
183: return 1;
184: }
185:
186: argc--;
187: argv++;
188: }
189:
190: if ( newdecay )
191: DecayUsage = pow(0.5, (Onef*Delta)/newdecay);
192:
193: if ( pdecay1 )
194: {
195: Trace(("old PriDecay = %f", PriDecay));
196: PriDecay = pow(0.5, Onef/pdecay2);
197: Trace((", new PriDecay = %f\n", PriDecay));
198: Trace(("old PriDecayBase = %ld", PriDecayBase));
199: f = pow(0.5, Onef/pdecay1) / PriDecay;
200: PriDecayBase = ((2*NZERO-1) * f - NZERO) / (Onef - f);
201: Trace((", new PriDecayBase = %ld\n", PriDecayBase));
202: }
203:
204: if ( rdecay )
205: {
206: Trace(("old RateDecay = %f", DecayRate));
207: DecayRate = pow(0.5, Onef/((float)rdecay));
208: Trace((", new RateDecay = %f\n", DecayRate));
209: }
210:
211:
212: if ( Percent != Oneh )
213: {
214: Percent /= Oneh;
215:
216: shconsts.sc_bio = shconsts.sc_bio * Percent;
217: shconsts.sc_tio = shconsts.sc_tio * Percent;
218: shconsts.sc_tick = shconsts.sc_tick * Percent;
219: shconsts.sc_click = shconsts.sc_click * Percent;
220: shconsts.sc_syscall = shconsts.sc_syscall * Percent;
221: }
222:
223: if ( Usage == ShowUsage )
224: printcharges(0);
225: else
226: if ( limits((struct lnode *)&shconsts, L_SETCOSTS) == SYSERROR )
227: error("L_SETCOSTS");
228:
229: return 0;
230: }
231:
232:
233:
234: void
235: getcosts()
236: {
237: if ( limits((struct lnode *)&shconsts, L_GETCOSTS) == SYSERROR )
238: error("L_GETCOSTS");
239: }
240:
241:
242:
243: char *
244: shflags(flags)
245: u_short flags;
246: {
247: register char * sp;
248: register int i;
249: register int j;
250: static char s[200];
251:
252: for ( sp = s, i = 1, j = 0 ; flags ; j++, i <<= 1 )
253: if ( flags & i )
254: {
255: flags &= ~i;
256: if ( sp != s )
257: *sp++ = ',';
258: sp += strlen(strcpy(sp, Flags[j]));
259: }
260:
261: return sp==s ? "<null>" : s;
262: }
263:
264:
265:
266: void
267: printcharges(showdefault)
268: int showdefault;
269: {
270: register float decay = ((log(.5)/log(DecayUsage))*Delta)/(60*60);
271:
272: if ( Percent == Oneh )
273: {
274: if ( Oldtick != shconsts.sc_tick )
275: Percent = (shconsts.sc_tick * Oneh) / Oldtick;
276: }
277: else
278: Percent *= Oneh;
279:
280: printf
281: (
282: "\
283: Scheduling flags = %s, charging percentage = %g%%,\n\
284: usage decay rate = %.8f (half-life %.1f %s),\n"
285: ,shflags(shconsts.sc_fl)
286: ,Percent
287: ,DecayUsage
288: ,decay < Onef ? decay * (60*60) : decay
289: ,decay < Onef ? "seconds" : "hours"
290: );
291:
292: printf
293: (
294: "\
295: Max. users = %d, max group nesting = %d.\n"
296: ,MAXUSERS
297: ,MAXGROUPS
298: );
299:
300: if ( Verbose && !showdefault )
301: printf
302: (
303: "\
304: active users = %d, active groups = %d.\n"
305: ,Users, Groups
306: );
307:
308: if ( !showdefault )
309: {
310: register float itot_charge = Oneh /
311: (
312: (float)shconsts.sc_syscallc * (float)shconsts.sc_syscall
313: + (float)shconsts.sc_bioc * (float)shconsts.sc_bio
314: + (float)shconsts.sc_tioc * (float)shconsts.sc_tio
315: + (float)shconsts.sc_tickc * (float)shconsts.sc_tick
316: + (float)shconsts.sc_clickc * (float)shconsts.sc_click
317: );
318:
319: printf
320: (
321: "\n\
322: Charge: syscall %6.0f%% bio %6.0f%% tio %6.0f%% tick %6.0f%% click %6.0f%%\n"
323: ,shconsts.sc_syscallc * (shconsts.sc_syscall * itot_charge)
324: ,shconsts.sc_bioc * (shconsts.sc_bio * itot_charge)
325: ,shconsts.sc_tioc * (shconsts.sc_tio * itot_charge)
326: ,shconsts.sc_tickc * (shconsts.sc_tick * itot_charge)
327: ,shconsts.sc_clickc * (shconsts.sc_click * itot_charge)
328: );
329: }
330:
331: if ( !Verbose )
332: return;
333:
334: if ( showdefault )
335: printf("\n");
336:
337: printf
338: (
339: "\
340: Costs: syscall %7lu bio %7lu tio %7lu tick %7lu click %7lu\n"
341: ,shconsts.sc_syscall
342: ,shconsts.sc_bio
343: ,shconsts.sc_tio
344: ,shconsts.sc_tick
345: ,shconsts.sc_click
346: );
347:
348: if ( !showdefault )
349: printf
350: (
351: "\
352: Counts: syscall %7lu bio %7lu tio %7lu tick %7lu click %7lu\n"
353: ,shconsts.sc_syscallc
354: ,shconsts.sc_bioc
355: ,shconsts.sc_tioc
356: ,shconsts.sc_tickc
357: ,shconsts.sc_clickc
358: );
359:
360: printf
361: (
362: "\n\
363: Process priority decay rate biased by \"nice\":-\n\
364: high priority (nice -%2d) %.4f (half-life %5.1f seconds),\n\
365: avg. priority (nice 0) %.4f (half-life %5.1f seconds),\n\
366: low priority (nice %2d) %.4f (half-life %5.1f seconds).\n\
367: \n\
368: Run rate decay rate %.4f (half-life %5.1f seconds).\n\
369: \n\
370: Minimum group share factor = %.3f,\n\
371: maximum user share factor = %.3f.\n\
372: \n\
373: Max. value for normal usage = %.3e,\n\
374: max. value for normal p_sharepri = %.3e,\n\
375: max. value for idle p_sharepri = %.3e.\n"
376: ,NZERO
377: ,PriDecay*(float)PriDecayBase/(float)(PriDecayBase+2*NZERO-1)
378: ,log(.5)/log(PriDecay*(float)PriDecayBase/(float)(PriDecayBase+2*NZERO-1))
379: ,PriDecay*(float)(PriDecayBase+NZERO)/(float)(PriDecayBase+2*NZERO-1)
380: ,log(.5)/log(PriDecay*(float)(PriDecayBase+NZERO)/(float)(PriDecayBase+2*NZERO-1))
381: ,NZERO-1
382: ,PriDecay
383: ,log(.5)/log(PriDecay)
384: ,DecayRate
385: ,log(.5)/log(DecayRate)
386: ,MINGSHARE
387: ,MAXUSHARE
388: ,MAXUSAGE
389: ,MAXUPRI
390: ,MAXPRI
391: );
392:
393: if ( showdefault )
394: return;
395:
396: printf
397: (
398: "\n\
399: High value of current normal usage = %.3e,\n\
400: high value of current p_sharepri = %.3e.\n"
401: ,MaxUsage
402: ,MaxSharePri
403: );
404: }
405:
406:
407:
408: /*VARARGS1*/
409: void
410: error(a, b)
411: char *a, *b;
412: {
413: extern errno;
414: extern int sys_nerr;
415: extern char *sys_errlist[];
416:
417: fprintf(stderr, "%s: error - ", Name);
418: fprintf(stderr, a, b);
419: if ( errno )
420: {
421: if ( errno < sys_nerr )
422: fprintf(stderr, " - %s\n", sys_errlist[errno]);
423: else
424: fprintf(stderr, " - Unknown error %d\n", errno);
425: }
426: else
427: putc('\n', stderr);
428: fprintf(stderr, Usage, Name);
429: exit(1);
430: }
431:
432:
433:
434: /*VARARGS1*/
435: int
436: atoo(p)
437: register char * p;
438: {
439: register int n = 0;
440: register int c;
441:
442: while ( (c = *p++) == ' ' || c == '\t' );
443:
444: while ( c >= '0' && c <= '7' )
445: {
446: n = n*8 + c - '0';
447: c = *p++;
448: }
449:
450: return n;
451: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.