00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <types.h>
00046 #include <proc.h>
00047 #include <current.h>
00048 #include <addrspace.h>
00049 #include <vnode.h>
00050 #include <vfs.h>
00051 #include <synch.h>
00052 #include <kern/fcntl.h>
00053
00054
00055
00056
00057 struct proc *kproc;
00058
00059
00060
00061
00062 #ifdef UW
00063
00064 static unsigned int proc_count;
00065
00066
00067 static struct semaphore *proc_count_mutex;
00068
00069 struct semaphore *no_proc_sem;
00070 #endif // UW
00071
00072
00073
00074
00075
00076
00077 static
00078 struct proc *
00079 proc_create(const char *name)
00080 {
00081 struct proc *proc;
00082
00083 proc = kmalloc(sizeof(*proc));
00084 if (proc == NULL) {
00085 return NULL;
00086 }
00087 proc->p_name = kstrdup(name);
00088 if (proc->p_name == NULL) {
00089 kfree(proc);
00090 return NULL;
00091 }
00092
00093 threadarray_init(&proc->p_threads);
00094 spinlock_init(&proc->p_lock);
00095
00096
00097 proc->p_addrspace = NULL;
00098
00099
00100 proc->p_cwd = NULL;
00101
00102 #ifdef UW
00103 proc->console = NULL;
00104 #endif // UW
00105
00106 return proc;
00107 }
00108
00109
00110
00111
00112 void
00113 proc_destroy(struct proc *proc)
00114 {
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 KASSERT(proc != NULL);
00125 KASSERT(proc != kproc);
00126
00127
00128
00129
00130
00131
00132
00133
00134 if (proc->p_cwd) {
00135 VOP_DECREF(proc->p_cwd);
00136 proc->p_cwd = NULL;
00137 }
00138
00139
00140 #ifndef UW // in the UW version, space destruction occurs in sys_exit, not here
00141 if (proc->p_addrspace) {
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 struct addrspace *as;
00153
00154 as_deactivate();
00155 as = curproc_setas(NULL);
00156 as_destroy(as);
00157 }
00158 #endif // UW
00159
00160 #ifdef UW
00161 if (proc->console) {
00162 vfs_close(proc->console);
00163 }
00164 #endif // UW
00165
00166 threadarray_cleanup(&proc->p_threads);
00167 spinlock_cleanup(&proc->p_lock);
00168
00169 kfree(proc->p_name);
00170 kfree(proc);
00171
00172 #ifdef UW
00173
00174
00175
00176
00177 P(proc_count_mutex);
00178 KASSERT(proc_count > 0);
00179 proc_count--;
00180
00181 if (proc_count == 0) {
00182 V(no_proc_sem);
00183 }
00184 V(proc_count_mutex);
00185 #endif // UW
00186
00187
00188 }
00189
00190
00191
00192
00193 void
00194 proc_bootstrap(void)
00195 {
00196 kproc = proc_create("[kernel]");
00197 if (kproc == NULL) {
00198 panic("proc_create for kproc failed\n");
00199 }
00200 #ifdef UW
00201 proc_count = 0;
00202 proc_count_mutex = sem_create("proc_count_mutex",1);
00203 if (proc_count_mutex == NULL) {
00204 panic("could not create proc_count_mutex semaphore\n");
00205 }
00206 no_proc_sem = sem_create("no_proc_sem",0);
00207 if (no_proc_sem == NULL) {
00208 panic("could not create no_proc_sem semaphore\n");
00209 }
00210 #endif // UW
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 struct proc *
00220 proc_create_runprogram(const char *name)
00221 {
00222 struct proc *proc;
00223 char *console_path;
00224
00225 proc = proc_create(name);
00226 if (proc == NULL) {
00227 return NULL;
00228 }
00229
00230 #ifdef UW
00231
00232 console_path = kstrdup("con:");
00233 if (console_path == NULL) {
00234 panic("unable to copy console path name during process creation\n");
00235 }
00236 if (vfs_open(console_path,O_WRONLY,0,&(proc->console))) {
00237 panic("unable to open the console during process creation\n");
00238 }
00239 kfree(console_path);
00240 #endif // UW
00241
00242
00243
00244 proc->p_addrspace = NULL;
00245
00246
00247
00248 #ifdef UW
00249
00250
00251
00252 if (curproc->p_cwd != NULL) {
00253 VOP_INCREF(curproc->p_cwd);
00254 proc->p_cwd = curproc->p_cwd;
00255 }
00256 #else // UW
00257 spinlock_acquire(&curproc->p_lock);
00258 if (curproc->p_cwd != NULL) {
00259 VOP_INCREF(curproc->p_cwd);
00260 proc->p_cwd = curproc->p_cwd;
00261 }
00262 spinlock_release(&curproc->p_lock);
00263 #endif // UW
00264
00265 #ifdef UW
00266
00267
00268
00269 P(proc_count_mutex);
00270 proc_count++;
00271 V(proc_count_mutex);
00272 #endif // UW
00273
00274 return proc;
00275 }
00276
00277
00278
00279
00280
00281 int
00282 proc_addthread(struct proc *proc, struct thread *t)
00283 {
00284 int result;
00285
00286 KASSERT(t->t_proc == NULL);
00287
00288 spinlock_acquire(&proc->p_lock);
00289 result = threadarray_add(&proc->p_threads, t, NULL);
00290 spinlock_release(&proc->p_lock);
00291 if (result) {
00292 return result;
00293 }
00294 t->t_proc = proc;
00295 return 0;
00296 }
00297
00298
00299
00300
00301
00302 void
00303 proc_remthread(struct thread *t)
00304 {
00305 struct proc *proc;
00306 unsigned i, num;
00307
00308 proc = t->t_proc;
00309 KASSERT(proc != NULL);
00310
00311 spinlock_acquire(&proc->p_lock);
00312
00313 num = threadarray_num(&proc->p_threads);
00314 for (i=0; i<num; i++) {
00315 if (threadarray_get(&proc->p_threads, i) == t) {
00316 threadarray_remove(&proc->p_threads, i);
00317 spinlock_release(&proc->p_lock);
00318 t->t_proc = NULL;
00319 return;
00320 }
00321 }
00322
00323 spinlock_release(&proc->p_lock);
00324 panic("Thread (%p) has escaped from its process (%p)\n", t, proc);
00325 }
00326
00327
00328
00329
00330
00331
00332 struct addrspace *
00333 curproc_getas(void)
00334 {
00335 struct addrspace *as;
00336 #ifdef UW
00337
00338
00339
00340 if (curproc == NULL) {
00341 return NULL;
00342 }
00343 #endif
00344
00345 spinlock_acquire(&curproc->p_lock);
00346 as = curproc->p_addrspace;
00347 spinlock_release(&curproc->p_lock);
00348 return as;
00349 }
00350
00351
00352
00353
00354
00355 struct addrspace *
00356 curproc_setas(struct addrspace *newas)
00357 {
00358 struct addrspace *oldas;
00359 struct proc *proc = curproc;
00360
00361 spinlock_acquire(&proc->p_lock);
00362 oldas = proc->p_addrspace;
00363 proc->p_addrspace = newas;
00364 spinlock_release(&proc->p_lock);
00365 return oldas;
00366 }