Research V5 development
[unix-history] / usr / sys / ken / slp.c
CommitLineData
fc8c4d9e
KT
1#
2/*
3 * Copyright 1973 Bell Telephone Laboratories Inc
4 */
5
6#include "../param.h"
7#include "../user.h"
8#include "../proc.h"
9#include "../text.h"
10#include "../systm.h"
11#include "../file.h"
12#include "../inode.h"
13#include "../buf.h"
14
15#define PS 0177776
16struct {
17 int integ;
18};
19
20sleep(chan, pri)
21{
22 register *rp, s;
23
24 u.u_dsleep = 0;
25 s = PS->integ;
26 rp = u.u_procp;
27 if(pri >= 0) {
28 if(issig())
29 goto psig;
30 rp->p_wchan = chan;
31 rp->p_stat = SWAIT;
32 rp->p_pri = pri;
33 spl0();
34 if(runin != 0) {
35 runin = 0;
36 wakeup(&runin);
37 }
38 swtch();
39 if(issig()) {
40 psig:
41 aretu(u.u_qsav);
42 return;
43 }
44 } else {
45 rp->p_wchan = chan;
46 rp->p_stat = SSLEEP;
47 rp->p_pri = pri;
48 spl0();
49 swtch();
50 }
51 PS->integ = s;
52}
53
54wakeup(chan)
55{
56 register struct proc *p;
57 register n, c;
58
59loop:
60 c = chan;
61 n = 0;
62 for(p = &proc[0]; p < &proc[NPROC]; p++)
63 if(p->p_wchan == c) {
64 if(runout!=0 && (p->p_flag&SLOAD)==0) {
65 runout = 0;
66 n++;
67 }
68 p->p_wchan = 0;
69 p->p_stat = SRUN;
70 runrun++;
71 }
72 if(n) {
73 chan = &runout;
74 goto loop;
75 }
76}
77
78sched()
79{
80 struct proc *p1;
81 register struct proc *rp;
82 register a, n;
83
84 /*
85 * find user to swap in
86 * of users ready, select one out longest
87 */
88
89 goto loop;
90
91sloop:
92 runin++;
93 sleep(&runin, PSWP);
94
95loop:
96 spl6();
97 n = -1;
98 for(rp = &proc[0]; rp < &proc[NPROC]; rp++)
99 if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 &&
100 rp->p_time > n) {
101 p1 = rp;
102 n = rp->p_time;
103 }
104 if(n == -1) {
105 runout++;
106 sleep(&runout, PSWP);
107 goto loop;
108 }
109
110 /*
111 * see if there is core for that process
112 */
113
114 spl0();
115 rp = p1;
116 a = rp->p_size;
117 if((rp=rp->p_textp) != NULL)
118 if(rp->x_ccount == 0)
119 a =+ rp->x_size;
120 if((a=malloc(coremap, a)) != NULL)
121 goto found2;
122
123 /*
124 * none found,
125 * look around for easy core
126 */
127
128 spl6();
129 for(rp = &proc[0]; rp < &proc[NPROC]; rp++)
130 if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD &&
131 rp->p_stat == SWAIT)
132 goto found1;
133
134 /*
135 * no easy core,
136 * if this process is deserving,
137 * look around for
138 * oldest process in core
139 */
140
141 if(n < 3)
142 goto sloop;
143 n = -1;
144 for(rp = &proc[0]; rp < &proc[NPROC]; rp++)
145 if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD &&
146 (rp->p_stat==SRUN || rp->p_stat==SSLEEP) &&
147 rp->p_time > n) {
148 p1 = rp;
149 n = rp->p_time;
150 }
151 if(n < 2)
152 goto sloop;
153 rp = p1;
154
155 /*
156 * swap user out
157 */
158
159found1:
160 spl0();
161 rp->p_flag =& ~SLOAD;
162 xswap(rp, 1, 0);
163 goto loop;
164
165 /*
166 * swap user in
167 */
168
169found2:
170 if((rp=p1->p_textp) != NULL) {
171 if(rp->x_ccount == 0) {
172 if(swap(rp->x_daddr, a, rp->x_size, B_READ))
173 goto swaper;
174 rp->x_caddr = a;
175 a =+ rp->x_size;
176 }
177 rp->x_ccount++;
178 }
179 rp = p1;
180 if(swap(rp->p_addr, a, rp->p_size, B_READ))
181 goto swaper;
182 mfree(swapmap, (rp->p_size+7)/8, rp->p_addr);
183 rp->p_addr = a;
184 rp->p_flag =| SLOAD;
185 rp->p_time = 0;
186 goto loop;
187
188swaper:
189 panic("swap error");
190}
191
192swtch()
193{
194 static int *p;
195 register i, n;
196 register struct proc *rp;
197
198 if(p == NULL)
199 p = &proc[0];
200 savu(u.u_rsav);
201 retu(proc[0].p_addr);
202
203loop:
204 rp = p;
205 p = NULL;
206 n = 127;
207 for(i=0; i<NPROC; i++) {
208 rp++;
209 if(rp >= &proc[NPROC])
210 rp = &proc[0];
211 if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)!=0) {
212 if(rp->p_pri < n) {
213 p = rp;
214 n = rp->p_pri;
215 }
216 }
217 }
218 if(p == NULL) {
219 p = rp;
220 idle();
221 goto loop;
222 }
223 rp = p;
224 retu(rp->p_addr);
225 sureg();
226 if(rp->p_flag&SSWAP) {
227 rp->p_flag =& ~SSWAP;
228 aretu(u.u_ssav);
229 }
230 return(1);
231}
232
233newproc()
234{
235 int a1, a2;
236 struct proc *p, *up;
237 register struct proc *rpp;
238 register *rip, n;
239
240 for(rpp = &proc[0]; rpp < &proc[NPROC]; rpp++)
241 if(rpp->p_stat == NULL)
242 goto found;
243 panic("no procs");
244
245found:
246 /*
247 * make proc entry for new proc
248 */
249
250 p = rpp;
251 rip = u.u_procp;
252 up = rip;
253 rpp->p_stat = SRUN;
254 rpp->p_flag = SLOAD;
255 rpp->p_uid = rip->p_uid;
256 rpp->p_ttyp = rip->p_ttyp;
257 rpp->p_textp = rip->p_textp;
258 rpp->p_pid = ++mpid;
259 rpp->p_ppid = rip->p_pid;
260 rpp->p_time = 0;
261
262 /*
263 * make duplicate entries
264 * where needed
265 */
266
267 for(rip = &u.u_ofile[0]; rip < &u.u_ofile[NOFILE];)
268 if((rpp = *rip++) != NULL)
269 rpp->f_count++;
270 if((rpp=up->p_textp) != NULL) {
271 rpp->x_count++;
272 rpp->x_ccount++;
273 }
274 u.u_cdir->i_count++;
275
276 /*
277 * swap out old process
278 * to make image of new proc
279 */
280
281 savu(u.u_rsav);
282 rpp = p;
283 u.u_procp = rpp;
284 rip = up;
285 n = rip->p_size;
286 a1 = rip->p_addr;
287 rpp->p_size = n;
288 a2 = malloc(coremap, n);
289 if(a2 == NULL) {
290 rip->p_stat = SIDL;
291 rpp->p_addr = a1;
292 savu(u.u_ssav);
293 xswap(rpp, 0, 0);
294 rpp->p_flag =| SSWAP;
295 rip->p_stat = SRUN;
296 } else {
297 rpp->p_addr = a2;
298 while(n--)
299 copyseg(a1++, a2++);
300 }
301 u.u_procp = rip;
302 return(0);
303}
304
305expand(newsize)
306{
307 int i, n;
308 register *p, a1, a2;
309
310 p = u.u_procp;
311 n = p->p_size;
312 p->p_size = newsize;
313 a1 = p->p_addr;
314 if(n >= newsize) {
315 mfree(coremap, n-newsize, a1+newsize);
316 return;
317 }
318 savu(u.u_rsav);
319 a2 = malloc(coremap, newsize);
320 if(a2 == NULL) {
321 savu(u.u_ssav);
322 xswap(p, 1, n);
323 p->p_flag =| SSWAP;
324 swtch();
325 /* no return */
326 }
327 p->p_addr = a2;
328 for(i=0; i<n; i++)
329 copyseg(a1+i, a2++);
330 mfree(coremap, n, a1);
331 retu(p->p_addr);
332 sureg();
333}