II. Triển khai
ALLOC
-
Tìm một "victim" page trong virtual memory:int find_victim_page(struct mm_struct *mm, int *retpgn)
- Lấy một page từ cuối hàng đợi
fifo_pgn
màmm
đang quản lý, lưu số thứ tự của page đó vàoretpgn
.
- Lấy một page từ cuối hàng đợi
-
Cấp phát các frame trên RAM và lưu trong danh sáchint alloc_pages_range(struct pcb_t *caller, int req_pgnum, struct framephy_struct **frm_lst)
frm_lst
:- Lặp qua
req_pgnum
lần. Ở mỗi bước lặp, kiểm tra có thể cấp phát 1 frame trong RAM. Nếu được, thêm frame vừa được cấp phát vào đầu danh sáchfrm_lst
. Nếu không, thực thi bước kế tiếp. - Tìm một frame
vicfpn
trong RAM và thay thế nó bằng một free frameswpfpn
trong SWAP. Việc lựa chọn mộtvicfpn
cần tìm một "victim" pagevicpgn
trong virtual memory bằng hàmfind_victim_page
. - Nếu việc tìm
vicpgn
hoặc lấy mộtswpfpn
trong SWAP thất bại thì giải phóng toàn bộ các frame đã được cấp phát trước đó và trả về lỗi. - Swap
vicfpn
trong RAM vớiswpfpn
trong SWAP. - Set page table entry tương ứng với
vicpgn
bằng hàmpte_set_swap
, thêmswpfpn
vào đầu danh sáchfrm_lst
.
- Lặp qua
-
Mapping các page tại địa chỉint vmap_page_range(struct pcb_t *caller, int addr, int pgnum, struct framephy_struct *frames, struct vm_rg_struct *ret_rg)
addr
với các frame trong danh sáchframes
:- Duyệt qua các page, set frame page table entry tương ứng với các page bằng hàm
pte_set_fpn
. Sau đó chèn các page đó theo thứ tự vào đầu danh sáchfifo_pgn
.
- Duyệt qua các page, set frame page table entry tương ứng với các page bằng hàm
-
Mapping virtual memory có kích thướcint vm_map_ram(struct pcb_t *caller, int astart, int aend, int mapstart, int incpgnum, struct vm_rg_struct *ret_rg)
aend - astart
với RAM:- Cấp phát trên RAM số lượng frame bằng với số page
incpgnum
trên virtual memory bằng hàmalloc_pages_range
, lưu các frame sau khi cấp phát thành một danh sáchfrm_lst
. - Nếu cấp phát thành công, map các page tại địa chỉ
mapstart
với các frame trong danh sáchfrm_lst
bằng hàmvmap_page_range
.
- Cấp phát trên RAM số lượng frame bằng với số page
-
Tăng kích thước vùng nhớ củaint inc_vma_limit(struct pcb_t *caller, int vmaid, int inc_sz)
vmaid
lên một khoảng bằnginc_sz
:- Kiểm tra
vmaid
nếu tăng kích thước có bị tràn qua các vmaid lân cận. Nếu có, trả về lỗi (return -1), ngược lại thực thi bước kế tiếp. - Dịch con trỏ
sbrk
vàvm_end
củavmaid
lên thêm 1 khoảng bằnginc_sz
. - Tiến hành mapping virtual memory vừa được cấp phát sang physical memory trên RAM bằng hàm
vm_map_ram
.
- Kiểm tra
-
Cấp phát cho regionint __alloc(struct pcb_t *caller, int vmaid, int rgid, int size, int *alloc_addr)
rgid
một vùng nhớ với kích thướcsize
, sử dụng khóa mutex để bảo vệ virtual memory:- Nếu kích thước vùng nhớ trống của area
vmaid >= size
thì cấp phát thành công. - Nếu không đủ vùng nhớ, tăng kích thước của area
vmaid
lên một khoảng bằng số lượng page vừa đủ chứasize
bằng hàminc_vma_limit
. - Sau khi tăng kích thước thành công, cấp phát
size
chorgid
. - Thêm fragment do paging gây ra sau khi cấp phát (nếu có) vào danh sách
vm_freerg_list
củamm
.
- Nếu kích thước vùng nhớ trống của area
-
Thực thi hàmint pgalloc(struct pcb_t *proc, uint32_t size, uint32_t reg_index)
__alloc
vớivmaid = 0
và ghi kết quả vào file output.
-
FREE
-
Giải phóng vùng nhớint __free(struct pcb_t *caller, int vmaid, int rgid)
rgid
, sử dụng khóa mutex để bảo vệ virtual memory:- Nếu
rgid < 0
hoặcrgid > PAGING_MAX_SYMTBL_SZ
hoặcsize rgid = 0
, trả về lỗi (return -1). - Gán kích thước của vùng nhớ
rgid
bằng 0, thêm vùng nhớ vừa được giải phóng vào danh sáchvm_freerg_list
màmm
quản lý.
- Nếu
-
Thực thi hàmint pgfree_data(struct pcb_t *proc, uint32_t reg_index)
__free
vớivmaid = 0
và ghi kết quả vào file output.
-
READ
-
int pg_getpage(struct mm_struct *mm, int pgn, int *fpn, struct pcb_t *caller)
Lấy frame
fpn
tương ứng với pagepgn
:- Nếu frame online (frame đang được lưu trên RAM ), trả về
fpn
. Nếu frame offline (frame đang được lưu trên SWAP), thực thi bước kế tiếp. - Tìm 1 "victim" page
vicpgn
trong virtual memory bằng hàmfind_victim_page
và lấy 1 free frameswpfpn
từ SWAP. Nếu thành công, thực thi bước kế tiếp. - Swap
vicfpn
tương ứngvicpgn
trong RAM vớiswpfpn
trong SWAP. - Swap
tgtfpn
tương ứngpgn
trong SWAP vớiswpfpn
trong RAM. - Set swap page table entry tương ứng với
vicpgn
bằng hàmpte_set_swap
. - Set frame page table entry tương ứng
pgn
bằng hàmpte_set_fpn
. - Thêm
pgn
vào danh sáchfifo_pgn
củamm
, trả vềfpn
.
Hình vẽ mô tả:
- Nếu frame online (frame đang được lưu trên RAM ), trả về
-
int pg_getval(struct mm_struct *mm, int addr, BYTE *data, struct pcb_t *caller)
Đọc giá trị của ô nhớ tại địa chỉ
addr
và lưu vàodata
:- Lấy page number và page offset từ
addr
. - Lấy frame number trong RAM hoặc SWAP tương ứng với page number trong virtual memory bằng hàm
pg_getpage
. - Nếu thành công, kết hợp frame number và page offset trả về physical memory. Đọc giá trị của địa chỉ vật lý này trong bộ nhớ vật lý bằng hàm
MEMPHY_read
.
- Lấy page number và page offset từ
-
int __read(struct pcb_t *caller, int vmaid, int rgid, int offset, BYTE *data)
Thực thi hàm
pg_getval
để đọc 1 byte giá trị ô nhớ ở vị tríoffset
trong vùng nhớrgid
vàodata
, sử dụng khóa mutex để bảo vệ virtual memory. -
int pgread(struct pcb_t *proc, uint32_t source, uint32_t offset, uint32_t destination)
Thực thi hàm
__read
vớivmaid = 0
và ghi kết quả vào file output.
-
WRITE
-
Ghiint pg_setval(struct mm_struct *mm, int addr, BYTE value, struct pcb_t *caller)
value
vào ô nhớ tại địa chỉaddr
:- Lấy page number và page offset từ
addr
. - Lấy frame number trong RAM hoặc SWAP tương ứng với page number trong virtual memory bằng hàm
pg_getpage
. - Nếu thành công, kết hợp frame number và page offset trả về physical memory. Ghi
value
vào địa chỉ vật lý này trong bộ nhớ vật lý bằng hàmMEMPHY_write
.
- Lấy page number và page offset từ
-
Thực thi hàmint __write(struct pcb_t *caller, int vmaid, int rgid, int offset, BYTE value)
pg_setval
để ghi 1 bytevalue
vào ô nhớ ở vị tríoffset
trong vùng nhớrgid
, sử dụng khóa mutex để bảo vệ virtual memory. -
Thực thi hàmint pgwrite(struct pcb_t *proc, BYTE data, uint32_t destination, uint32_t offset)
__write
vớivmaid = 0
và ghi kết quả vào file output.
-