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: }