Advertisement
Guest User

DesignDoc

a guest
Jan 20th, 2018
311
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.27 KB | None | 0 0
  1. +--------------------------+
  2. | CS333 |
  3. | PROJECT 2: USER PROGRAMS |
  4. | DESIGN DOCUMENT |
  5. +--------------------------+
  6.  
  7.  
  8.  
  9. ---- GROUP ----
  10.  
  11. >> Fill in the names and email addresses of your group members.
  12. Hossam El-Safty
  13. Saed Hamdy
  14. Mohamed Mourad
  15.  
  16. ---- PRELIMINARIES ----
  17.  
  18. >> If you have any preliminary comments on your submission, notes for the
  19. >> TAs, or extra credit, please give them here.
  20.  
  21. >> Please cite any offline or online sources you consulted while
  22. >> preparing your submission, other than the Pintos documentation, course
  23. >> text, lecture notes, and course staff.
  24.  
  25. ARGUMENT PASSING
  26. ================
  27.  
  28. ---- DATA STRUCTURES ----
  29.  
  30. >> A1: Copy here the declaration of each new or changed `struct' or
  31. >> `struct' member, global or static variable, `typedef', or
  32. >> enumeration. Identify the purpose of each in 25 words or less.
  33.  
  34. None
  35.  
  36. ---- ALGORITHMS ----
  37.  
  38. >> A2: Briefly describe how you implemented argument parsing. How do
  39. >> you arrange for the elements of argv[] to be in the right order?
  40. >> How do you avoid overflowing the stack page?
  41.  
  42. How to implement argument parsing?
  43. ----------------------------------
  44. The most important part was to setup the stack. We did it inside setup_stack ()
  45. after page is installed, when the stack has been initialized.
  46.  
  47. Process_execute provides file_name, including command and arguments
  48. string. First, we took a copy separated the first token, We use command as the new thread's name, and pass down the string to start_process(), load() and setup_stack().
  49. When setting up the stack, we memcpy the CMDLINE string and then separated it to callculate the argc then reserve memory for argv[] and use the file name itself this time to add these argument in stack and save its places in the right order in argv[] Then add alignment,
  50. scan the argv[] backward to get each argu address and push it into the page underneath
  51. the alignment to generate argv[], finally argv, argc and return address.
  52.  
  53. Way of arranging for the elements of argv[] to be in the right order.
  54. --------------------------------------------------------------------
  55. We scan through the argv[] backwards, so that the first element we get is
  56. the last argument address, the last element we get is the first argument address. We can just keep
  57. decreasing esp pointer to setup the argv[] elements.
  58.  
  59. How to avoid overflowing the stack page?
  60. ----------------------------------------
  61. The thing is we decided not to check the esp pointer until it fails. Our
  62. implementation didn’t pre-count how much space do we need, just go through
  63. everything, make the change, like add another argv element, when necessary. But
  64. this leaves us two way to deal with overflowing, one is checking esp’s validity
  65. every time before use it, the other one is letting it fails, and we handle it in
  66. the page fault exception, which is exit(-1) the running thread whenever the
  67. address is invalid. We chose the latter approach since the first approach seems
  68. have too much burden and it make sense to terminate the process if it provides
  69. too much arguments.
  70.  
  71. ---- RATIONALE ----
  72.  
  73. >> A3: Why does Pintos implement strtok_r() but not strtok()?
  74.  
  75. The only difference between strtok_r() and strtok() is that the save_ptr
  76. (placeholder) in strtok_r() is provided by the caller. In pintos, the kernel
  77. separates commands into command line (executable name) and arguments. So we need
  78. to put the address of the arguments somewhere we can reach later,but we didn't use it as we took a copy of the input line .
  79.  
  80. >> A4: In Pintos, the kernel separates commands into a executable name
  81. >> and arguments. In Unix-like systems, the shell does this
  82. >> separation. Identify at least two advantages of the Unix approach.
  83.  
  84. 1) Shortening the time inside kernel
  85. 2) Robust checking. Checking whether the executable is there before passing it
  86. to kernel to avoid kernel fail. Checking whether the arguments are over the
  87. limit.
  88. 3) Once it can separate the commands, it can do advanced pre-processing, acting
  89. more like an interpreter not only an interface. Like passing more than 1 set
  90. of command line at a time, i.e. cd; mkdir tmp; touch test; and pipe.
  91.  
  92.  
  93. SYSTEM CALLS
  94. ============
  95.  
  96. ---- DATA STRUCTURES ----
  97.  
  98. >> B1: Copy here the declaration of each new or changed `struct' or
  99. >> `struct' member, global or static variable, `typedef', or
  100. >> enumeration. Identify the purpose of each in 25 words or less.
  101.  
  102. in thread.h
  103. the following is added to struct thread
  104. bool child_start;
  105. int exit_error;
  106. int fd_count;
  107. struct semaphore *child_lock;
  108. struct list files;
  109. struct list children;
  110. int wait_child;
  111.  
  112. struct child { // chiled status
  113.  
  114. bool done ;
  115. int tid ;
  116. struct list_elem elem;
  117. int exit_error ;
  118. };
  119. in syscall.c
  120. we added the following struct
  121. struct file_struct
  122. {
  123. struct file* ptr;
  124. int fd;
  125. struct list_elem elem;
  126. };
  127.  
  128. >> B2: Describe how file descriptors are associated with open files.
  129. >> Are file descriptors unique within the entire OS or just within a
  130. >> single process?
  131.  
  132. each file has a different fd,
  133. so The file descriptor is unique within the entire OS.
  134.  
  135. ---- ALGORITHMS ----
  136.  
  137. >> B3: Describe your code for reading and writing user data from the
  138. >> kernel.
  139.  
  140. 1-reading:
  141. we first check if all pointers are valid and get the values in an args,
  142. if it valid continue, not valid then exit from the process
  143. we call a method read which perform the reading task.
  144. if fd equal 0, then read from user,
  145. else, search for the file pointed to the fd number, then read using a file_read implemented function
  146. we should acquire then release the file_lock between this process.
  147.  
  148. 2-writing:
  149. we first check if all pointers are valid and get the values in an args,
  150. if it valid continue, not valid then exit from the process
  151. we call a method write which perform the writing task.
  152. if fd equal 0, then write from user,
  153. else, search for the file pointed to the fd number, then write using a file_write implemented function
  154. we should acquire then release the file_lock between this process.
  155.  
  156. >> B4: Suppose a system call causes a full page (4,096 bytes) of data
  157. >> to be copied from user space into the kernel. What is the least
  158. >> and the greatest possible number of inspections of the page table
  159. >> (e.g. calls to pagedir_get_page()) that might result? What about
  160. >> for a system call that only copies 2 bytes of data? Is there room
  161. >> for improvement in these numbers, and how much?
  162.  
  163. >> B5: Briefly describe your implementation of the "wait" system call
  164. >> and how it interacts with process termination.
  165.  
  166. >> B6: Any access to user program memory at a user-specified address
  167. >> can fail due to a bad pointer value. Such accesses must cause the
  168. >> process to be terminated. System calls are fraught with such
  169. >> accesses, e.g. a "write" system call requires reading the system
  170. >> call number from the user stack, then each of the call's three
  171. >> arguments, then an arbitrary amount of user memory, and any of
  172. >> these can fail at any point. This poses a design and
  173. >> error-handling problem: how do you best avoid obscuring the primary
  174. >> function of code in a morass of error-handling? Furthermore, when
  175. >> an error is detected, how do you ensure that all temporarily
  176. >> allocated resources (locks, buffers, etc.) are freed? In a few
  177. >> paragraphs, describe the strategy or strategies you adopted for
  178. >> managing these issues. Give an example.
  179.  
  180. to avoid pointing out of user memory we implemented a method which
  181. check if the address in the valid range of user memory or not
  182. this method used on calling a method and after that for each of the needed
  183. arguments for the corresponding system call, if any invalid terminate,
  184. if there is a lock we release it, if there is opened files, they are closed.
  185.  
  186. ---- SYNCHRONIZATION ----
  187.  
  188. >> B7: The "exec" system call returns -1 if loading the new executable
  189. >> fails, so it cannot return before the new executable has completed
  190. >> loading. How does your code ensure this? How is the load
  191. >> success/failure status passed back to the thread that calls "exec"?
  192.  
  193. Our design is to have the child_start bool recorded in the parent’s
  194. thread. Child is responsible to set child_start. Child can get the parent
  195. thread through a thread pointer parent in its struct
  196.  
  197. when the parent call function create it will wait on a semaphore until the
  198. created chiled wake him up again but first the child would set the child_start
  199. bool of his parent, so when the parent wake up it will check it's bool to know if
  200. the child load correctly or not .
  201.  
  202.  
  203. >> B8: Consider parent process P with child process C. How do you
  204. >> ensure proper synchronization and avoid race conditions when P
  205. >> calls wait(C) before C exits? After C exits? How do you ensure
  206. >> that all resources are freed in each case? How about when P
  207. >> terminates without waiting, before C exits? After C exits? Are
  208. >> there any special cases?
  209.  
  210. We use a child struct to represents each child process’s status, and a
  211. list of child_status (children) inside parent’s struct to represent all the children that
  212. the process has. And use a semaphore to prevent race condition.
  213.  
  214. Child is responsible to set it’s status in parent’s thread struct. When parent
  215. exits, the list inside it will be free.
  216.  
  217. So, in the cases above:
  218. * P calls wait(C) before C exits
  219. P will call sema_down (&thread_current()->child_lock) and wait until it exits and set the
  220. child->done bool that is related to (true) and update its status. Then parent retrieves
  221. the child’s exit status.
  222.  
  223. * P calls wait(C) after C exits
  224. P will find the c->done true so it wont wait on the semaphore but return the exist status directly.
  225.  
  226. * P terminates without waiting before C exits
  227. The list inside P will be free,When C tries
  228. to set it’s status and find out parent has exited, it will ignore it and continue to execute.
  229.  
  230. * P terminates after C exits
  231. The same thing happen to P, which is free all the resources P has.
  232.  
  233.  
  234.  
  235. ---- RATIONALE ----
  236.  
  237. >> B9: Why did you choose to implement access to user memory from the
  238. >> kernel in the way that you did?
  239.  
  240. >> B10: What advantages or disadvantages can you see to your design
  241. >> for file descriptors?
  242.  
  243. >> B11: The default tid_t to pid_t mapping is the identity mapping.
  244. >> If you changed it, what advantages are there to your approach?
  245.  
  246. SURVEY QUESTIONS
  247. ================
  248.  
  249. Answering these questions is optional, but it will help us improve the
  250. course in future quarters. Feel free to tell us anything you
  251. want--these questions are just to spur your thoughts. You may also
  252. choose to respond anonymously in the course evaluations at the end of
  253. the quarter.
  254.  
  255. >> In your opinion, was this assignment, or any one of the three problems
  256. >> in it, too easy or too hard? Did it take too long or too little time?
  257.  
  258. >> Did you find that working on a particular part of the assignment gave
  259. >> you greater insight into some aspect of OS design?
  260.  
  261. >> Is there some particular fact or hint we should give students in
  262. >> future quarters to help them solve the problems? Conversely, did you
  263. >> find any of our guidance to be misleading?
  264.  
  265. >> Do you have any suggestions for the TAs to more effectively assist
  266. >> students, either for future quarters or the remaining projects?
  267.  
  268. >> Any other comments?
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement