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 segment.
4488:  * 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: }