4350 # 4351 #include "../param.h" 4352 #include "../systm.h" 4353 #include "../user.h" 4354 #include "../proc.h" 4355 #include "../text.h" 4356 #include "../inode.h" 4357 4358 /* Swap out process p. 4359 * The ff flag causes its core to be freed-- 4360 * it may be off when called to create an image for a 4361 * child process in newproc. 4362 * Os is the old size of the data area of the process, 4363 * and is supplied during core expansion swaps. 4364 * 4365 * panic: out of swap space 4366 * panic: swap error -- IO error 4367 */ 4368 xswap(p, ff, os) 4369 int *p; 4370 { register *rp, a; 4371 4372 rp = p; 4373 if(os == 0) 4374 os = rp->p_size; 4375 a = malloc(swapmap, (rp->p_size+7)/8); 4376 if(a == NULL) 4377 panic("out of swap space"); 4378 xccdec(rp->p_textp); 4379 rp->p_flag =| SLOCK; 4380 if(swap(a, rp->p_addr, os, 0)) 4381 panic("swap error"); 4382 if(ff) 4383 mfree(coremap, os, rp->p_addr); 4384 rp->p_addr = a; 4385 rp->p_flag =& ~(SLOAD|SLOCK); 4386 rp->p_time = 0; 4387 if(runout) { 4388 runout = 0; 4389 wakeup(&runout); 4390 } 4391 } 4392 /* ------------------------ */ 4393 4394 /* 4395 * relinquish use of the shared text segment 4396 * of a process. 4397 */ 4398 xfree() 4399 { 4400 register *xp, *ip; 4401 4402 if((xp=u.u_procp->p_textp) != NULL) { 4403 u.u_procp->p_textp = NULL; 4404 xccdec(xp); 4405 if(--xp->x_count == 0) { 4406 ip = xp->x_iptr; 4407 if((ip->i_mode&ISVTX) == 0) { 4408 xp->x_iptr = NULL; 4409 mfree(swapmap, (xp->x_size+7)/8, xp->x_daddr); 4410 ip->i_flag =& ~ITEXT; 4411 iput(ip); 4412 } 4413 } 4414 } 4415 } 4416 /* ------------------------ */ 4417 4418 /* Attach to a shared text segment. 4419 * If there is no shared text, just return. 4420 * If there is, hook up to it: 4421 * if it is not currently being used, it has to be read 4422 * in from the inode (ip) and established in the swap space. 4423 * If it is being used, but is not currently in core, 4424 * a swap has to be done to get it back. 4425 * The full coroutine glory has to be invoked-- 4426 * see slp.c-- because if the calling process 4427 * is misplaced in core the text image might not fit. 4428 * Quite possibly the code after "out:" could check to 4429 * see if the text does fit and simply swap it in. 4430 * 4431 * panic: out of swap space 4432 */ 4433 xalloc(ip) 4434 int *ip; 4435 { 4436 register struct text *xp; 4437 register *rp, ts; 4438 4439 if(u.u_arg[1] == 0) return; 4440 rp = NULL; 4441 for(xp = &text[0]; xp < &text[NTEXT]; xp++) 4442 if(xp->x_iptr == NULL) { 4443 if(rp == NULL) 4444 rp = xp; 4445 } else 4446 if(xp->x_iptr == ip) { 4447 xp->x_count++; 4448 u.u_procp->p_textp = xp; 4449 goto out; 4450 } 4451 if((xp=rp) == NULL) panic("out of text"); 4452 xp->x_count = 1; 4453 xp->x_ccount = 0; 4454 xp->x_iptr = ip; 4455 ts = ((u.u_arg[1]+63)>>6) & 01777; 4456 xp->x_size = ts; 4457 if((xp->x_daddr = malloc(swapmap, (ts+7)/8)) == NULL) 4458 panic("out of swap space"); 4459 expand(USIZE+ts); 4460 estabur(0, ts, 0, 0); 4461 u.u_count = u.u_arg[1]; 4462 u.u_offset[1] = 020; 4463 u.u_base = 0; 4464 readi(ip); 4465 rp = u.u_procp; 4466 rp->p_flag =| SLOCK; 4467 swap(xp->x_daddr, rp->p_addr+USIZE, ts, 0); 4468 rp->p_flag =& ~SLOCK; 4469 rp->p_textp = xp; 4470 rp = ip; 4471 rp->i_flag =| ITEXT; 4472 rp->i_count++; 4473 expand(USIZE); 4474 out: 4475 if(xp->x_ccount == 0) { 4476 savu(u.u_rsav); 4477 savu(u.u_ssav); 4478 xswap(u.u_procp, 1, 0); 4479 u.u_procp->p_flag =| SSWAP; 4480 swtch(); 4481 /* no return */ 4482 } 4483 xp->x_ccount++; 4484 } 4485 /* ------------------------ */ 4486 4487 /* Decrement the in-core usage count of a shared text 4488 * segment. When it drops to zero, free the core space. 4489 */ 4490 xccdec(xp) 4491 int *xp; 4492 { 4493 register *rp; 4494 4495 if((rp=xp)!=NULL && rp->x_ccount!=0) 4496 if(--rp->x_ccount == 0) 4497 mfree(coremap, rp->x_size, rp->x_caddr); 4498 } 4499 /* ------------------------ */