Dokumentation
Especially 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.
Copy-On-Write (COW)
Pages to be copied while using fork
(and, when possible, send
-receive
-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)).
- Note
- Pages originally marked as read-only should (obviously) not become writable after such a copy operation. However, reference counting might be required for such pages as well (for example, if the parent process
exit
s, the text segment has to be available still until the child exits).
For send
-recv
or reply
-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. However, IPC should fall back on the previous mechanism when COW is not applicable.
However, StuBS IPC should still be able to handle buffers with different alignments and fall back on the previous copy mechanism when COW is not applicable.
Test Application
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.
The forkapp
has to be changed accordingly:
Demonstrate the advantages of COW regarding the memory usage by printing the available page frames:
- Before Scheduler::schedule() in main()
- In IdleThread::action()