Commit | Line | Data |
---|---|---|
f1b39b19 KT |
1 | # |
2 | /* | |
3 | */ | |
4 | ||
5 | #include "../param.h" | |
6 | #include "../systm.h" | |
7 | #include "../user.h" | |
8 | #include "../proc.h" | |
9 | #include "../text.h" | |
10 | #include "../inode.h" | |
11 | ||
12 | /* | |
13 | * Swap out process p. | |
14 | * The ff flag causes its core to be freed-- | |
15 | * it may be off when called to create an image for a | |
16 | * child process in newproc. | |
17 | * Os is the old size of the data area of the process, | |
18 | * and is supplied during core expansion swaps. | |
19 | * | |
20 | * panic: out of swap space | |
21 | * panic: swap error -- IO error | |
22 | */ | |
23 | xswap(p, ff, os) | |
24 | int *p; | |
25 | { | |
26 | register *rp, a; | |
27 | ||
28 | rp = p; | |
29 | if(os == 0) | |
30 | os = rp->p_size; | |
31 | a = malloc(swapmap, (rp->p_size+7)/8); | |
32 | if(a == NULL) | |
33 | panic("out of swap space"); | |
34 | xccdec(rp->p_textp); | |
35 | rp->p_flag =| SLOCK; | |
36 | if(swap(a, rp->p_addr, os, 0)) | |
37 | panic("swap error"); | |
38 | if(ff) | |
39 | mfree(coremap, os, rp->p_addr); | |
40 | rp->p_addr = a; | |
41 | rp->p_flag =& ~(SLOAD|SLOCK); | |
42 | rp->p_time = 0; | |
43 | if(runout) { | |
44 | runout = 0; | |
45 | wakeup(&runout); | |
46 | } | |
47 | } | |
48 | ||
49 | /* | |
50 | * relinquish use of the shared text segment | |
51 | * of a process. | |
52 | */ | |
53 | xfree() | |
54 | { | |
55 | register *xp, *ip; | |
56 | ||
57 | if((xp=u.u_procp->p_textp) != NULL) { | |
58 | u.u_procp->p_textp = NULL; | |
59 | xccdec(xp); | |
60 | if(--xp->x_count == 0) { | |
61 | ip = xp->x_iptr; | |
62 | if((ip->i_mode&ISVTX) == 0) { | |
63 | xp->x_iptr = NULL; | |
64 | mfree(swapmap, (xp->x_size+7)/8, xp->x_daddr); | |
65 | ip->i_flag =& ~ITEXT; | |
66 | iput(ip); | |
67 | } | |
68 | } | |
69 | } | |
70 | } | |
71 | ||
72 | /* | |
73 | * Attach to a shared text segment. | |
74 | * If there is no shared text, just return. | |
75 | * If there is, hook up to it: | |
76 | * if it is not currently being used, it has to be read | |
77 | * in from the inode (ip) and established in the swap space. | |
78 | * If it is being used, but is not currently in core, | |
79 | * a swap has to be done to get it back. | |
80 | * The full coroutine glory has to be invoked-- | |
81 | * see slp.c-- because if the calling process | |
82 | * is misplaced in core the text image might not fit. | |
83 | * Quite possibly the code after "out:" could check to | |
84 | * see if the text does fit and simply swap it in. | |
85 | * | |
86 | * panic: out of swap space | |
87 | */ | |
88 | xalloc(ip) | |
89 | int *ip; | |
90 | { | |
91 | register struct text *xp; | |
92 | register *rp, ts; | |
93 | ||
94 | if(u.u_arg[1] == 0) | |
95 | return; | |
96 | rp = NULL; | |
97 | for(xp = &text[0]; xp < &text[NTEXT]; xp++) | |
98 | if(xp->x_iptr == NULL) { | |
99 | if(rp == NULL) | |
100 | rp = xp; | |
101 | } else | |
102 | if(xp->x_iptr == ip) { | |
103 | xp->x_count++; | |
104 | u.u_procp->p_textp = xp; | |
105 | goto out; | |
106 | } | |
107 | if((xp=rp) == NULL) | |
108 | panic("out of text"); | |
109 | xp->x_count = 1; | |
110 | xp->x_ccount = 0; | |
111 | xp->x_iptr = ip; | |
112 | ts = ((u.u_arg[1]+63)>>6) & 01777; | |
113 | xp->x_size = ts; | |
114 | if((xp->x_daddr = malloc(swapmap, (ts+7)/8)) == NULL) | |
115 | panic("out of swap space"); | |
116 | expand(USIZE+ts); | |
117 | estabur(0, ts, 0, 0); | |
118 | u.u_count = u.u_arg[1]; | |
119 | u.u_offset[1] = 020; | |
120 | u.u_base = 0; | |
121 | readi(ip); | |
122 | rp = u.u_procp; | |
123 | rp->p_flag =| SLOCK; | |
124 | swap(xp->x_daddr, rp->p_addr+USIZE, ts, 0); | |
125 | rp->p_flag =& ~SLOCK; | |
126 | rp->p_textp = xp; | |
127 | rp = ip; | |
128 | rp->i_flag =| ITEXT; | |
129 | rp->i_count++; | |
130 | expand(USIZE); | |
131 | ||
132 | out: | |
133 | if(xp->x_ccount == 0) { | |
134 | savu(u.u_rsav); | |
135 | savu(u.u_ssav); | |
136 | xswap(u.u_procp, 1, 0); | |
137 | u.u_procp->p_flag =| SSWAP; | |
138 | swtch(); | |
139 | /* no return */ | |
140 | } | |
141 | xp->x_ccount++; | |
142 | } | |
143 | ||
144 | /* | |
145 | * Decrement the in-core usage count of a shared text segment. | |
146 | * When it drops to zero, free the core space. | |
147 | */ | |
148 | xccdec(xp) | |
149 | int *xp; | |
150 | { | |
151 | register *rp; | |
152 | ||
153 | if((rp=xp)!=NULL && rp->x_ccount!=0) | |
154 | if(--rp->x_ccount == 0) | |
155 | mfree(coremap, rp->x_size, rp->x_caddr); | |
156 | } |