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