Advertisement
Guest User

Untitled

a guest
May 21st, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.23 KB | None | 0 0
  1. /*
  2. * Copyright (c) 2013
  3. * The President and Fellows of Harvard College.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29.  
  30. /*
  31. * Process support.
  32. *
  33. * There is (intentionally) not much here; you will need to add stuff
  34. * and maybe change around what's already present.
  35. *
  36. * p_lock is intended to be held when manipulating the pointers in the
  37. * proc structure, not while doing any significant work with the
  38. * things they point to. Rearrange this (and/or change it to be a
  39. * regular lock) as needed.
  40. *
  41. * Unless you're implementing multithreaded user processes, the only
  42. * process that will have more than one thread is the kernel process.
  43. */
  44.  
  45. #include <types.h>
  46. #include <spl.h>
  47. #include <proc.h>
  48. #include <current.h>
  49. #include <addrspace.h>
  50. #include <vnode.h>
  51. //per wait_pid
  52. #include <synch.h>
  53. // per l'opzionalità
  54. #include <opt-pidtable.h>
  55.  
  56. #define MAXPROC 64
  57.  
  58. /*
  59. * The process for the kernel; this holds all the kernel-only threads.
  60. */
  61. struct proc *kproc;
  62. struct proc* pidtable[MAXPROC]; //vettore di puntatori
  63.  
  64. /*
  65. * Create a proc structure.
  66. */
  67. static
  68. struct proc *
  69. proc_create(const char *name)
  70. {
  71. struct proc *proc;
  72.  
  73. proc = kmalloc(sizeof(*proc));
  74. if (proc == NULL) {
  75. return NULL;
  76. }
  77. proc->p_name = kstrdup(name);
  78. if (proc->p_name == NULL) {
  79. kfree(proc);
  80. return NULL;
  81. }
  82.  
  83. proc->p_numthreads = 0;
  84. spinlock_init(&proc->p_lock);
  85.  
  86. /* VM fields */
  87. proc->p_addrspace = NULL;
  88.  
  89. /* VFS fields */
  90. proc->p_cwd = NULL;
  91.  
  92. //added by me
  93. //start at zero, 1 is set when a process ends
  94. proc->sem = sem_create(name, 0);
  95. //
  96.  
  97. #if OPT_PIDTABLE==1
  98. proc-> pid = proc_addToTable(proc);
  99. kprintf("New process assigned pid: %d\n", proc->pid);
  100. #endif
  101.  
  102. return proc;
  103. }
  104.  
  105.  
  106. /*
  107. * Destroy a proc structure.
  108. *
  109. * Note: nothing currently calls this. Your wait/exit code will
  110. * probably want to do so.
  111. */
  112. void
  113. proc_destroy(struct proc *proc)
  114. {
  115. /*
  116. * You probably want to destroy and null out much of the
  117. * process (particularly the address space) at exit time if
  118. * your wait/exit design calls for the process structure to
  119. * hang around beyond process exit. Some wait/exit designs
  120. * do, some don't.
  121. */
  122.  
  123. KASSERT(proc != NULL);
  124. KASSERT(proc != kproc);
  125.  
  126. /*
  127. * We don't take p_lock in here because we must have the only
  128. * reference to this structure. (Otherwise it would be
  129. * incorrect to destroy it.)
  130. */
  131.  
  132. /* VFS fields */
  133. if (proc->p_cwd) {
  134. VOP_DECREF(proc->p_cwd);
  135. proc->p_cwd = NULL;
  136. }
  137.  
  138. /* VM fields */
  139. if (proc->p_addrspace) {
  140. /*
  141. * If p is the current process, remove it safely from
  142. * p_addrspace before destroying it. This makes sure
  143. * we don't try to activate the address space while
  144. * it's being destroyed.
  145. *
  146. * Also explicitly deactivate, because setting the
  147. * address space to NULL won't necessarily do that.
  148. *
  149. * (When the address space is NULL, it means the
  150. * process is kernel-only; in that case it is normally
  151. * ok if the MMU and MMU- related data structures
  152. * still refer to the address space of the last
  153. * process that had one. Then you save work if that
  154. * process is the next one to run, which isn't
  155. * uncommon. However, here we're going to destroy the
  156. * address space, so we need to make sure that nothing
  157. * in the VM system still refers to it.)
  158. *
  159. * The call to as_deactivate() must come after we
  160. * clear the address space, or a timer interrupt might
  161. * reactivate the old address space again behind our
  162. * back.
  163. *
  164. * If p is not the current process, still remove it
  165. * from p_addrspace before destroying it as a
  166. * precaution. Note that if p is not the current
  167. * process, in order to be here p must either have
  168. * never run (e.g. cleaning up after fork failed) or
  169. * have finished running and exited. It is quite
  170. * incorrect to destroy the proc structure of some
  171. * random other process while it's still running...
  172. */
  173. struct addrspace *as;
  174.  
  175. if (proc == curproc) {
  176. as = proc_setas(NULL);
  177. as_deactivate();
  178. }
  179. else {
  180. as = proc->p_addrspace;
  181. proc->p_addrspace = NULL;
  182. }
  183. as_destroy(as);
  184. }
  185.  
  186. KASSERT(proc->p_numthreads == 0);
  187. spinlock_cleanup(&proc->p_lock);
  188. sem_destroy(proc->sem);
  189.  
  190. #if OPT_PIDTABLE==1
  191. int value = proc_removeFromTable((int)proc->pid);
  192. if( value == 0)
  193. kprintf("Process correctly removed from table\n");
  194. #endif
  195.  
  196. kfree(proc->p_name);
  197. kfree(proc);
  198. }
  199.  
  200. /*
  201. * Create the process structure for the kernel.
  202. */
  203. void
  204. proc_bootstrap(void)
  205. {
  206. kproc = proc_create("[kernel]");
  207. if (kproc == NULL) {
  208. panic("proc_create for kproc failed\n");
  209. }
  210. }
  211.  
  212. /*
  213. * Create a fresh proc for use by runprogram.
  214. *
  215. * It will have no address space and will inherit the current
  216. * process's (that is, the kernel menu's) current directory.
  217. */
  218. struct proc *
  219. proc_create_runprogram(const char *name)
  220. {
  221. struct proc *newproc;
  222.  
  223. newproc = proc_create(name);
  224. if (newproc == NULL) {
  225. return NULL;
  226. }
  227.  
  228. /* VM fields */
  229.  
  230. newproc->p_addrspace = NULL;
  231.  
  232. /* VFS fields */
  233.  
  234. /*
  235. * Lock the current process to copy its current directory.
  236. * (We don't need to lock the new process, though, as we have
  237. * the only reference to it.)
  238. */
  239. spinlock_acquire(&curproc->p_lock);
  240. if (curproc->p_cwd != NULL) {
  241. VOP_INCREF(curproc->p_cwd);
  242. newproc->p_cwd = curproc->p_cwd;
  243. }
  244. spinlock_release(&curproc->p_lock);
  245.  
  246. #if OPT_PIDTABLE==1
  247. newproc-> pid = proc_addToTable(newproc);
  248. kprintf("New process assigned pid: %d\n", newproc->pid);
  249. #endif
  250.  
  251. return newproc;
  252. }
  253.  
  254. /*
  255. * Add a thread to a process. Either the thread or the process might
  256. * or might not be current.
  257. *
  258. * Turn off interrupts on the local cpu while changing t_proc, in
  259. * case it's current, to protect against the as_activate call in
  260. * the timer interrupt context switch, and any other implicit uses
  261. * of "curproc".
  262. */
  263. int
  264. proc_addthread(struct proc *proc, struct thread *t)
  265. {
  266. int spl;
  267.  
  268. KASSERT(t->t_proc == NULL);
  269.  
  270. spinlock_acquire(&proc->p_lock);
  271. proc->p_numthreads++;
  272. spinlock_release(&proc->p_lock);
  273.  
  274. spl = splhigh();
  275. t->t_proc = proc;
  276. splx(spl);
  277.  
  278. return 0;
  279. }
  280.  
  281. /*
  282. * Remove a thread from its process. Either the thread or the process
  283. * might or might not be current.
  284. *
  285. * Turn off interrupts on the local cpu while changing t_proc, in
  286. * case it's current, to protect against the as_activate call in
  287. * the timer interrupt context switch, and any other implicit uses
  288. * of "curproc".
  289. */
  290. void
  291. proc_remthread(struct thread *t)
  292. {
  293. struct proc *proc;
  294. int spl;
  295.  
  296. proc = t->t_proc;
  297. KASSERT(proc != NULL);
  298.  
  299. spinlock_acquire(&proc->p_lock);
  300. KASSERT(proc->p_numthreads > 0);
  301. proc->p_numthreads--;
  302. spinlock_release(&proc->p_lock);
  303.  
  304. spl = splhigh();
  305. t->t_proc = NULL;
  306. splx(spl);
  307. }
  308.  
  309. /*
  310. * Fetch the address space of (the current) process.
  311. *
  312. * Caution: address spaces aren't refcounted. If you implement
  313. * multithreaded processes, make sure to set up a refcount scheme or
  314. * some other method to make this safe. Otherwise the returned address
  315. * space might disappear under you.
  316. */
  317. struct addrspace *
  318. proc_getas(void)
  319. {
  320. struct addrspace *as;
  321. struct proc *proc = curproc;
  322.  
  323. if (proc == NULL) {
  324. return NULL;
  325. }
  326.  
  327. spinlock_acquire(&proc->p_lock);
  328. as = proc->p_addrspace;
  329. spinlock_release(&proc->p_lock);
  330. return as;
  331. }
  332.  
  333. /*
  334. * Change the address space of (the current) process. Return the old
  335. * one for later restoration or disposal.
  336. */
  337. struct addrspace *
  338. proc_setas(struct addrspace *newas)
  339. {
  340. struct addrspace *oldas;
  341. struct proc *proc = curproc;
  342.  
  343. KASSERT(proc != NULL);
  344.  
  345. spinlock_acquire(&proc->p_lock);
  346. oldas = proc->p_addrspace;
  347. proc->p_addrspace = newas;
  348. spinlock_release(&proc->p_lock);
  349. return oldas;
  350. }
  351.  
  352. //added by me
  353. int
  354. proc_wait(struct proc *p) { //p è il figlio
  355. P(p->sem); //il processo si ferma e aspetta
  356. int status = p->lastStatus;
  357.  
  358. /* get address space of current process and destroy */
  359. while( p->p_numthreads != 0); //destroy si può fare solo quando numthread è 0
  360. proc_destroy(p);
  361. //as_destroy(as); // libera as: già fatto in proc destroy
  362.  
  363. return status;
  364. }
  365.  
  366. #if OPT_PIDTABLE==1
  367. // pidtable functions:::::::::::::::::::::
  368. void proc_initTable(void) {
  369. int i;
  370. // 1 e 0 dovrebbero essere vietati
  371. for( i=2 ; i<MAXPROC ; i++){
  372. pidtable[i] = NULL;
  373. }
  374. }
  375.  
  376. int proc_addToTable(struct proc *p) {
  377. int i;
  378. // 1 e 0 dovrebbero essere vietati
  379. for( i=2 ; i<MAXPROC ; i++){
  380. if(pidtable[i] == NULL ) {
  381. pidtable[i] = p;
  382. return i;
  383. }
  384. }
  385. return -1;
  386. }
  387.  
  388. int proc_removeFromTable(int pid) {
  389. if( pid == 1 || pid == 0)
  390. return -1;
  391.  
  392. //ATTENZIONE: è un altro processo che rimuove spesso
  393. pidtable[pid] = NULL;
  394. return 0;
  395. }
  396.  
  397. pid_t proc_getpid(void) {
  398. return curproc-> pid;
  399. }
  400.  
  401. struct proc* proc_getproc(int pid) {
  402. return pidtable[pid];
  403. }
  404. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement