fork requires copying a lot of pages – although some of them will stay the same on both parent and child and therefore can be shared. This sharing not only saves memory but improves the performance as well.
Pages to be copied while using
reply should be displayed (mapped) in the other address space unless a write access occurs – only then they will be physically copied.
To detect a write access, the pages concerned have to be mapped as read-only. Thus, the page fault handler is triggered on a write operation. A shadow page table for all affected physical page addresses should count the number of references on COW pages. On a write operation, the reference gets decremented and the page needs to be copied (unless there is only this one reference left). Additionally, the page mapping of the process needs to be adjusted (don't forget to invalidate those pages in the translation lookaside buffer (TLB)).
exits, the text segment has to be available still until the child exits).
send the contents of the buffers can only be copied using COW if the message size is at least equal to the page size (leftovers have to be copied physically) and the alignment of both buffers are identical. To fulfill the latter requirement, the buffers are best placed at page borders. This can be achieved using the C++ specifier
alignas(x) (or the GCC/LLVM extension
__attribute__((aligned (x)))), whereas the constant
x defines the alignment in bytes.
Again, you should extensively test your implementation. The application of the previous assignment can be re-used with a few adjustments (alignment) as mentioned above.
forkapp has to be changed accordingly:
Demonstrate the advantages of COW regarding the memory usage by printing the available page frames: