Skip to content

Latest commit

 

History

53 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

# P3B
## Part I: Null Pointer Dereference

For the initial process,
- vm.c inituvm()
  - start mapping pages at 0x2000 instead of 0
  
- proc.c userinit()
  - p->sz, the high address of mapped memory, needs to start 0x2000 higher than 
    before (PGSIZE+0x2000)
  - p->tf->esp, the high address of the stack, needs to start 0x2000 higher than
    before (PGSIZE+0x2000)
  - p->tf->eip, the instruction pointer, starts at the first address of the code
    segment (now 0x2000)
      
- exec.c exec()
  - sz marks the first address of the code segment, updated to 0x2000
  
- vm.c copyuvm()
  - fork calls copyuvm to copy the code, stack, and heap. The original copyuvm()
    starts at address 0. Updated to 0x2000.
      
- kernel makefile and user makefile
  - for the initial process, needs to start at 0x2000
  
## Part II: xv6 Memory Layout
### Moving the stack to the top of mapped memory
- proc.h
  - use proc.stackLow member to track the lowest mapped address of the stack.
    Assume the highest address of the stack is USERTOP.

- exec.c exec()
  - allocate initial one page stack below USERTOP instead of after the code
    segment
  - sz unchanged (still immediately after code, but no longer updated because
    we have stackLow and sp to track stack segment)
  - sp starts at stackHigh, which is USERTOP, and decreases as the stack grows
    downward
  - stackLow set to lowest mapped address, which starts one page below USERTOP

- vm.c copyuvm() - called from fork
  - Need to copy the code+heap and stack segments separately. Separately loop
    over code+heap segment and loop over stack segment to copy each segment.
      
- syscall.c fetchint(), fetchstr(), argptr()
  - All bound checking needs to be updated to account for separating the stack
    segment from the code+heap

### Growing the stack
- trap.c trap()
  - Add new switch case for T_PGFLT. New code used to grow stack as detected by
    a page fault trap
  - If in the 5 guard pages, then kill user process (do not grow stack if it 
    would grow into heap)
  - If not in the next adjacent page under stack, then kill user process (do not
    grow stack if requesting an address beyond the adjacent page)
  - Otherwise, keep growing stack page-by-page using allocuvm()

- sysproc.c sys_sbrk()
  - To prevent heap from growing into stack, check that the requested bytes do
    not trespass the 5 guard pages. Fail the sbrk() by returning -1 if it does.

Files changed:
p3b/xv6/xv6-fa20/kernel/defs.h
p3b/xv6/xv6-fa20/kernel/exec.c
p3b/xv6/xv6-fa20/kernel/proc.c
p3b/xv6/xv6-fa20/kernel/syscall.c
p3b/xv6/xv6-fa20/kernel/sysproc.c
p3b/xv6/xv6-fa20/kernel/trap.c
p3b/xv6/xv6-fa20/kernel/vm.c
p3b/xv6/xv6-fa20/user/makefile.mk
Tests (so far):
p3b/xv6/xv6-fa20/user/heap.c
p3b/xv6/xv6-fa20/user/testStackOnePage.c
p3b/xv6/xv6-fa20/user/testheap1.c
p3b/xv6/xv6-fa20/user/teststack1.c
p3b/xv6/xv6-fa20/user/teststack2.c
p3b/xv6/xv6-fa20/user/teststack3.c
p3b/xv6/xv6-fa20/user/teststack4.c
p3b/xv6/xv6-fa20/user/teststack5.c
p3b/xv6/xv6-fa20/user/teststack6.c
p3b/xv6/xv6-fa20/user/teststack7.c
p3b/xv6/xv6-fa20/user/teststack8.c
p3b/xv6/xv6-fa20/user/teststackpiazza198.c

# P3A
## data structures
  - use union seg_t to ensure the client segments are 64 bytes
  
## shm_server
- Setup
  - Create and map memory page using shm_open()
  - Truncate file to single page using ftruncate() and getpagesize()
  - Map the memory page for sharing using mmap()
- Mutex initialization
  - Intialize shareable mutex lock in the first 64 byte segment of the shared
    memory page using p_thread_* functions as specified in the design and 
    provided skeleton code.
  - The remaining 63 segments are for storing client data. This is done by 
    setting start of the client segments 64 bytes after the starting address of
    the shared memory page. Later on in the while loop, we can use array indices
    to loop over the client segments.
- Terminating the server process
  - Set up signal handlers by linking SIGINT and SIGTERM to the function pointer.
  - Calls exit_handler() to clean up the server process.
  - Unmaps and closes the shared memory page.
- Printing server output
  - Enters infinite while loop.
  - Treats any segments where pid = 0 as empty.
  - Otherwise, if segment pid is not 0, outputs according to specification.
  
## shm_client
- Setup
  - Invalid input args - exit:
    - Must specify the client string
    - Client string cannot exceed 9 characters
  - Open existing shared memory page using shm_open()
  - Map shared memory using mmap()
- Mutex lock
  - Set up the shared mutex lock by setting the mutex lock to the first byte of 
    the shared memory (recall we use first segment to store shared mutex)
  - Critical sections for the client are the initialization and the termination.
    - Can have conflict where two clients try to reserve the same segment.
    - Can have conflict where multiple processes attempt to terminate same client. ***test this?
- Terminating the client process
  - Same as server process, link SIGINT and SIGTERM to exit_handler()
  - Clean up the client segment and free it for reuse by setting pid = 0.
- Reservation
  - Find the first open segment by traversing and finding pid = 0.
  - Initialize stats_t struct
  - Use library functions timespec_get and ctime for the birth string and birth seconds
  - Max clients
    - After looping through shared memory for an open spot, exit if available spot not found.
- Printing client output
  - Enter infinite while loop.
  - Traverse segments, again using client array indices.
  - Assume any pid != 0 is a valid client segment to print.
  - Calculate elapsed seconds and milliseconds using timespec_get to retrieve current time.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages