More generally, you implement an atomic action:
BEGIN pre-commit phase commit post-commit phase ENDTwo variants: write-ahead log and wirte-behind log
Commons:
Advantages:
Disadvantages:
Uncommons:
log planned writes commit install new data
Scan forward through log, looking for commited but not installed cells
Advantages:
log old cell values install new data commitWhen recovery:
Scan backward through log and restore old uncommited cells
Advantages:
Motivation: High throughput
Tell P2 the file size
P2 is later told that the file size is wrong
P2 aborts its transaction
Tell P2 the file size
P2 is later told that the file size is wrong
P2 adds compensating actions to make the last story correct
Advantage: Faster
Advantage: Debuggable
If referrence M doesn't satisfy P1_base <= M < P1_bound, report
Disadvantages:
e.g. jmp 100038 (absolute address which can be accessed by one process can't be accessed by another)
Solution: Use relative address (Position Independent Code)Disadvantage: A bit slower than absolute address
P1_base <= M + P1_base < P1_bound: M is the virtual address
Now, absolute address can be used via virtual address
Each process has 8 base-bound pairs:
Page size = 2^12 = 4096 bytes
4 bytes in virtual memory table (an entry) represents 4096 bytes of virtual memory (a page)
With 1-level page table, 2^22 = 4 MB is needed for page table per process in X86, which is too large
So 2-level page table is applied
At start, the process traps. The kernel must deal with the page fault
// pfault(va, cp, atype): va is virtual address, cp is current process's pointer and atype is access type void pfault(void *va, struct proc *cp, int atype) { /* tell where this page should live on disk, return 0 if invalid * otherwise address in swap space * kernel maintains its own page table in a software-defined */ if (swapmap(va, cp) == 0) kill(cp, SIGSGSV); else { /* * vppn, vaa = removal_policy(); * write out vppn to disk * record in desired page to save physical transaction * page_table[vaa] = 0; * page_table[va] = vppn; */ } }