Old s-solbourne.c
1 /* System dependent file for Solbourne workstations running OS/MP. */
2 /*
3 * Copyright 1990 Solbourne Computer, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Solbourne not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. Solbourne Computer, Inc. makes no representations
12 * about the suitability of this software for any purpose. It is provided
13 * "as is" without express or implied warranty.
14 *
15 * SOLBOURNE COMPUTER, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 * IN NO EVENT SHALL SOLBOURNE COMPUTER, INC. BE LIABLE FOR ANY SPECIAL,
18 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
20 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Author: William Kucharski, Solbourne Computer, Inc.
24 * kucharsk@Solbourne.COM
25 * ...!{boulder,sun,uunet}!stan!kucharsk
26 */
27 /* LINTLIBRARY */
28
29 #include <sys/syscall.h>
30 #include <sys/param.h>
31 #include <sys/dk.h>
32 #include <nlist.h>
33
34 extern char *xmalloc(/* int nbytes */);
35
36 extern int open(), read();
37 extern long lseek();
38
39 extern char *kernelSymbols();
40
41 long cp_time[MAXNCPUS][CPUSTATES];
42 long cp_old[MAXNCPUS][CPUSTATES];
43 int kmem; /* file descriptor of /dev/kmem. */
44 struct nlist nl[] = {
45 #define X_CP_TIME 0
46 { "_cp_mp_time" },
47 { "" },
48 };
49
50 /* Called at the beginning to inquire how many bars are needed. */
51
52 int
53 num_bars()
54 {
55 unsigned int status;
56 unsigned int width;
57 unsigned int type;
58
59 int numcpus = 0;
60 int proc;
61
62 if (syscall(SYS_getcpustatus, &status, &width, &type) < 0) {
63 perror("getcpustatus");
64 exit(1);
65 }
66
67 for (proc = 0; proc < width; proc++)
68 if ((status >> proc) & 1)
69 numcpus++;
70
71 return(numcpus);
72 }
73
74 /*
75 * Indicates how many levels each bar has. For most machines, each bar will
76 * have the same stuff. But one can, for instance, display memory use on one
77 * bar, processor levels on others, etc.
78 */
79 void
80 bar_items(nbars, items)
81 int nbars;
82 int items[]; /* nbars items in this */
83 {
84 int i;
85
86 for(i = 0; i < nbars; i++)
87 items[i] = CPUSTATES;
88 }
89
90 /* Called after num_bars to ask for the bar names */
91 /* ARGSUSED */
92 char **
93 label_bars(nbars)
94 {
95 extern char *strcpy(/* char *, const char * */);
96
97 char **names;
98 int i;
99
100 static char hname[MAXHOSTNAMELEN];
101
102 if (gethostname(hname, MAXHOSTNAMELEN) < 0) {
103 perror("gethostname");
104 hname[0] = '\0';
105 }
106
107 names = (char **) xmalloc(nbars * sizeof(char *));
108 if (nbars == 1) {
109 char buf[MAXHOSTNAMELEN + 3];
110 (void) sprintf(buf, "%s: ", hname);
111 names[0] = strcpy(xmalloc(strlen(buf) + 1), buf);
112 } else {
113 for(i = 0; i < nbars; i++) {
114 char buf[MAXHOSTNAMELEN + 6];
115
116 /*
117 * Use bar number % 10 in case someone someday can stuff
118 * more than 9 CPUs into a Solbourne box...
119 */
120
121 (void) sprintf(buf, "%s(%d): ", hname, (i % 10));
122 names[i] = strcpy(xmalloc(strlen(buf) + 1), buf);
123 }
124 }
125 return names;
126 }
127
128 /*
129 * Called after the bars are created to perform any machine dependent
130 * initializations.
131 */
132 /* ARGSUSED */
133 void
134 init_bars(nbars)
135 int nbars;
136 {
137
138 if ((kmem = open("/dev/kmem", 0)) < 0) {
139 perror("/dev/kmem");
140 exit(1);
141 }
142 (void)nlist(kernelSymbols?kernelSymbols:"/vmunix", nl);
143 if (lseek(kmem, (long) nl[X_CP_TIME].n_value, 0) !=
144 (long) nl[X_CP_TIME].n_value)
145 perror("lseek");
146 if (read(kmem, (char *) cp_old, sizeof(cp_old)) !=
147 sizeof(cp_old))
148 perror("read");
149 }
150
151 /*
152 * This procedure gets called every interval to compute and display the
153 * bars. It should call draw_bar() with the bar number, the array of
154 * integer values to display in the bar, and the number of values in
155 * the array.
156 */
157 /* ARGSUSED */
158 void
159 display_bars(nbars)
160 {
161 int nstates;
162 int states[CPUSTATES];
163 int i;
164 int proc;
165
166 extern void draw_bar(/*int bar_num, int *states, int num_states*/);
167
168 if (lseek(kmem, (long) nl[X_CP_TIME].n_value, 0) !=
169 (long) nl[X_CP_TIME].n_value)
170 perror("lseek");
171 if (read(kmem, (char *) cp_time, sizeof(cp_time)) !=
172 sizeof(cp_time))
173 perror("read");
174
175 #define delta(cpu, cpustate) ((int) (cp_time[cpu][(cpustate)] - \
176 cp_old[cpu][(cpustate)]))
177
178 for (proc = 0; proc < nbars; proc++) {
179 nstates = 0;
180 states[nstates++] = delta(proc, CP_IDLE);
181 states[nstates++] = delta(proc, CP_USER);
182 states[nstates++] = delta(proc, CP_NICE);
183 states[nstates++] = delta(proc, CP_SYS);
184 draw_bar(proc, states, nstates);
185 for (i = 0; i < CPUSTATES; i ++)
186 cp_old[proc][i] = cp_time[proc][i];
187 }
188 }