Skip to content

Commit

Permalink
Merge pull request chyyuu#32 from roastduck/fix
Browse files Browse the repository at this point in the history
Improve chyyuu#29 and apply it to all the labs
  • Loading branch information
chyyuu authored Mar 16, 2018
2 parents a870924 + 15e3c36 commit 65f5b0b
Show file tree
Hide file tree
Showing 14 changed files with 1,107 additions and 600 deletions.
4 changes: 2 additions & 2 deletions labcodes/lab2/kern/mm/default_pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <string.h>
#include <default_pmm.h>

/* In the first fitting algorithm, the allocator keeps a list of free blocks
/* In the First Fit algorithm, the allocator keeps a list of free blocks
* (known as the free list). Once receiving a allocation request for memory,
* it scans along the list for the first block that is large enough to satisfy
* the request. If the chosen block is significantly larger than requested, it
Expand Down Expand Up @@ -91,7 +91,7 @@
* Reset the fields of the pages, such as `p->ref` and `p->flags` (PageProperty)
* (5.3)
* Try to merge blocks at lower or higher addresses. Notice: This should
* change some pages's `p->property` correctly.
* change some pages' `p->property` correctly.
*/
free_area_t free_area;

Expand Down
131 changes: 85 additions & 46 deletions labcodes/lab3/kern/mm/default_pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,95 @@
#include <string.h>
#include <default_pmm.h>

/* In the first fit algorithm, the allocator keeps a list of free blocks (known as the free list) and,
on receiving a request for memory, scans along the list for the first block that is large enough to
satisfy the request. If the chosen block is significantly larger than that requested, then it is
usually split, and the remainder added to the list as another free block.
Please see Page 196~198, Section 8.2 of Yan Wei Min's chinese book "Data Structure -- C programming language"
/* In the First Fit algorithm, the allocator keeps a list of free blocks
* (known as the free list). Once receiving a allocation request for memory,
* it scans along the list for the first block that is large enough to satisfy
* the request. If the chosen block is significantly larger than requested, it
* is usually splitted, and the remainder will be added into the list as
* another free block.
* Please refer to Page 196~198, Section 8.2 of Yan Wei Min's Chinese book
* "Data Structure -- C programming language".
*/
// LAB2 EXERCISE 1: YOUR CODE
// you should rewrite functions: default_init,default_init_memmap,default_alloc_pages, default_free_pages.
// you should rewrite functions: `default_init`, `default_init_memmap`,
// `default_alloc_pages`, `default_free_pages`.
/*
* Details of FFMA
* (1) Prepare: In order to implement the First-Fit Mem Alloc (FFMA), we should manage the free mem block use some list.
* The struct free_area_t is used for the management of free mem blocks. At first you should
* be familiar to the struct list in list.h. struct list is a simple doubly linked list implementation.
* You should know howto USE: list_init, list_add(list_add_after), list_add_before, list_del, list_next, list_prev
* Another tricky method is to transform a general list struct to a special struct (such as struct page):
* you can find some MACRO: le2page (in memlayout.h), (in future labs: le2vma (in vmm.h), le2proc (in proc.h),etc.)
* (2) default_init: you can reuse the demo default_init fun to init the free_list and set nr_free to 0.
* free_list is used to record the free mem blocks. nr_free is the total number for free mem blocks.
* (3) default_init_memmap: CALL GRAPH: kern_init --> pmm_init-->page_init-->init_memmap--> pmm_manager->init_memmap
* This fun is used to init a free block (with parameter: addr_base, page_number).
* First you should init each page (in memlayout.h) in this free block, include:
* p->flags should be set bit PG_property (means this page is valid. In pmm_init fun (in pmm.c),
* the bit PG_reserved is setted in p->flags)
* if this page is free and is not the first page of free block, p->property should be set to 0.
* if this page is free and is the first page of free block, p->property should be set to total num of block.
* p->ref should be 0, because now p is free and no reference.
* We can use p->page_link to link this page to free_list, (such as: list_add_before(&free_list, &(p->page_link)); )
* Finally, we should sum the number of free mem block: nr_free+=n
* (4) default_alloc_pages: search find a first free block (block size >=n) in free list and reszie the free block, return the addr
* of malloced block.
* (4.1) So you should search freelist like this:
* list_entry_t le = &free_list;
* while((le=list_next(le)) != &free_list) {
* ....
* (4.1.1) In while loop, get the struct page and check the p->property (record the num of free block) >=n?
* struct Page *p = le2page(le, page_link);
* if(p->property >= n){ ...
* (4.1.2) If we find this p, then it' means we find a free block(block size >=n), and the first n pages can be malloced.
* Some flag bits of this page should be setted: PG_reserved =1, PG_property =0
* unlink the pages from free_list
* (4.1.2.1) If (p->property >n), we should re-caluclate number of the the rest of this free block,
* (such as: le2page(le,page_link))->property = p->property - n;)
* (4.1.3) re-caluclate nr_free (number of the the rest of all free block)
* (4.1.4) return p
* (4.2) If we can not find a free block (block size >=n), then return NULL
* (5) default_free_pages: relink the pages into free list, maybe merge small free blocks into big free blocks.
* (5.1) according the base addr of withdrawed blocks, search free list, find the correct position
* (from low to high addr), and insert the pages. (may use list_next, le2page, list_add_before)
* (5.2) reset the fields of pages, such as p->ref, p->flags (PageProperty)
* (5.3) try to merge low addr or high addr blocks. Notice: should change some pages's p->property correctly.
* (1) Preparation:
* In order to implement the First-Fit Memory Allocation (FFMA), we should
* manage the free memory blocks using a list. The struct `free_area_t` is used
* for the management of free memory blocks.
* First, you should get familiar with the struct `list` in list.h. Struct
* `list` is a simple doubly linked list implementation. You should know how to
* USE `list_init`, `list_add`(`list_add_after`), `list_add_before`, `list_del`,
* `list_next`, `list_prev`.
* There's a tricky method that is to transform a general `list` struct to a
* special struct (such as struct `page`), using the following MACROs: `le2page`
* (in memlayout.h), (and in future labs: `le2vma` (in vmm.h), `le2proc` (in
* proc.h), etc).
* (2) `default_init`:
* You can reuse the demo `default_init` function to initialize the `free_list`
* and set `nr_free` to 0. `free_list` is used to record the free memory blocks.
* `nr_free` is the total number of the free memory blocks.
* (3) `default_init_memmap`:
* CALL GRAPH: `kern_init` --> `pmm_init` --> `page_init` --> `init_memmap` -->
* `pmm_manager` --> `init_memmap`.
* This function is used to initialize a free block (with parameter `addr_base`,
* `page_number`). In order to initialize a free block, firstly, you should
* initialize each page (defined in memlayout.h) in this free block. This
* procedure includes:
* - Setting the bit `PG_property` of `p->flags`, which means this page is
* valid. P.S. In function `pmm_init` (in pmm.c), the bit `PG_reserved` of
* `p->flags` is already set.
* - If this page is free and is not the first page of a free block,
* `p->property` should be set to 0.
* - If this page is free and is the first page of a free block, `p->property`
* should be set to be the total number of pages in the block.
* - `p->ref` should be 0, because now `p` is free and has no reference.
* After that, We can use `p->page_link` to link this page into `free_list`.
* (e.g.: `list_add_before(&free_list, &(p->page_link));` )
* Finally, we should update the sum of the free memory blocks: `nr_free += n`.
* (4) `default_alloc_pages`:
* Search for the first free block (block size >= n) in the free list and reszie
* the block found, returning the address of this block as the address required by
* `malloc`.
* (4.1)
* So you should search the free list like this:
* list_entry_t le = &free_list;
* while((le=list_next(le)) != &free_list) {
* ...
* (4.1.1)
* In the while loop, get the struct `page` and check if `p->property`
* (recording the num of free pages in this block) >= n.
* struct Page *p = le2page(le, page_link);
* if(p->property >= n){ ...
* (4.1.2)
* If we find this `p`, it means we've found a free block with its size
* >= n, whose first `n` pages can be malloced. Some flag bits of this page
* should be set as the following: `PG_reserved = 1`, `PG_property = 0`.
* Then, unlink the pages from `free_list`.
* (4.1.2.1)
* If `p->property > n`, we should re-calculate number of the rest
* pages of this free block. (e.g.: `le2page(le,page_link))->property
* = p->property - n;`)
* (4.1.3)
* Re-caluclate `nr_free` (number of the the rest of all free block).
* (4.1.4)
* return `p`.
* (4.2)
* If we can not find a free block with its size >=n, then return NULL.
* (5) `default_free_pages`:
* re-link the pages into the free list, and may merge small free blocks into
* the big ones.
* (5.1)
* According to the base address of the withdrawed blocks, search the free
* list for its correct position (with address from low to high), and insert
* the pages. (May use `list_next`, `le2page`, `list_add_before`)
* (5.2)
* Reset the fields of the pages, such as `p->ref` and `p->flags` (PageProperty)
* (5.3)
* Try to merge blocks at lower or higher addresses. Notice: This should
* change some pages' `p->property` correctly.
*/
free_area_t free_area;

Expand Down
131 changes: 85 additions & 46 deletions labcodes/lab4/kern/mm/default_pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,95 @@
#include <string.h>
#include <default_pmm.h>

/* In the first fit algorithm, the allocator keeps a list of free blocks (known as the free list) and,
on receiving a request for memory, scans along the list for the first block that is large enough to
satisfy the request. If the chosen block is significantly larger than that requested, then it is
usually split, and the remainder added to the list as another free block.
Please see Page 196~198, Section 8.2 of Yan Wei Min's chinese book "Data Structure -- C programming language"
/* In the First Fit algorithm, the allocator keeps a list of free blocks
* (known as the free list). Once receiving a allocation request for memory,
* it scans along the list for the first block that is large enough to satisfy
* the request. If the chosen block is significantly larger than requested, it
* is usually splitted, and the remainder will be added into the list as
* another free block.
* Please refer to Page 196~198, Section 8.2 of Yan Wei Min's Chinese book
* "Data Structure -- C programming language".
*/
// LAB2 EXERCISE 1: YOUR CODE
// you should rewrite functions: default_init,default_init_memmap,default_alloc_pages, default_free_pages.
// you should rewrite functions: `default_init`, `default_init_memmap`,
// `default_alloc_pages`, `default_free_pages`.
/*
* Details of FFMA
* (1) Prepare: In order to implement the First-Fit Mem Alloc (FFMA), we should manage the free mem block use some list.
* The struct free_area_t is used for the management of free mem blocks. At first you should
* be familiar to the struct list in list.h. struct list is a simple doubly linked list implementation.
* You should know howto USE: list_init, list_add(list_add_after), list_add_before, list_del, list_next, list_prev
* Another tricky method is to transform a general list struct to a special struct (such as struct page):
* you can find some MACRO: le2page (in memlayout.h), (in future labs: le2vma (in vmm.h), le2proc (in proc.h),etc.)
* (2) default_init: you can reuse the demo default_init fun to init the free_list and set nr_free to 0.
* free_list is used to record the free mem blocks. nr_free is the total number for free mem blocks.
* (3) default_init_memmap: CALL GRAPH: kern_init --> pmm_init-->page_init-->init_memmap--> pmm_manager->init_memmap
* This fun is used to init a free block (with parameter: addr_base, page_number).
* First you should init each page (in memlayout.h) in this free block, include:
* p->flags should be set bit PG_property (means this page is valid. In pmm_init fun (in pmm.c),
* the bit PG_reserved is setted in p->flags)
* if this page is free and is not the first page of free block, p->property should be set to 0.
* if this page is free and is the first page of free block, p->property should be set to total num of block.
* p->ref should be 0, because now p is free and no reference.
* We can use p->page_link to link this page to free_list, (such as: list_add_before(&free_list, &(p->page_link)); )
* Finally, we should sum the number of free mem block: nr_free+=n
* (4) default_alloc_pages: search find a first free block (block size >=n) in free list and reszie the free block, return the addr
* of malloced block.
* (4.1) So you should search freelist like this:
* list_entry_t le = &free_list;
* while((le=list_next(le)) != &free_list) {
* ....
* (4.1.1) In while loop, get the struct page and check the p->property (record the num of free block) >=n?
* struct Page *p = le2page(le, page_link);
* if(p->property >= n){ ...
* (4.1.2) If we find this p, then it' means we find a free block(block size >=n), and the first n pages can be malloced.
* Some flag bits of this page should be setted: PG_reserved =1, PG_property =0
* unlink the pages from free_list
* (4.1.2.1) If (p->property >n), we should re-caluclate number of the the rest of this free block,
* (such as: le2page(le,page_link))->property = p->property - n;)
* (4.1.3) re-caluclate nr_free (number of the the rest of all free block)
* (4.1.4) return p
* (4.2) If we can not find a free block (block size >=n), then return NULL
* (5) default_free_pages: relink the pages into free list, maybe merge small free blocks into big free blocks.
* (5.1) according the base addr of withdrawed blocks, search free list, find the correct position
* (from low to high addr), and insert the pages. (may use list_next, le2page, list_add_before)
* (5.2) reset the fields of pages, such as p->ref, p->flags (PageProperty)
* (5.3) try to merge low addr or high addr blocks. Notice: should change some pages's p->property correctly.
* (1) Preparation:
* In order to implement the First-Fit Memory Allocation (FFMA), we should
* manage the free memory blocks using a list. The struct `free_area_t` is used
* for the management of free memory blocks.
* First, you should get familiar with the struct `list` in list.h. Struct
* `list` is a simple doubly linked list implementation. You should know how to
* USE `list_init`, `list_add`(`list_add_after`), `list_add_before`, `list_del`,
* `list_next`, `list_prev`.
* There's a tricky method that is to transform a general `list` struct to a
* special struct (such as struct `page`), using the following MACROs: `le2page`
* (in memlayout.h), (and in future labs: `le2vma` (in vmm.h), `le2proc` (in
* proc.h), etc).
* (2) `default_init`:
* You can reuse the demo `default_init` function to initialize the `free_list`
* and set `nr_free` to 0. `free_list` is used to record the free memory blocks.
* `nr_free` is the total number of the free memory blocks.
* (3) `default_init_memmap`:
* CALL GRAPH: `kern_init` --> `pmm_init` --> `page_init` --> `init_memmap` -->
* `pmm_manager` --> `init_memmap`.
* This function is used to initialize a free block (with parameter `addr_base`,
* `page_number`). In order to initialize a free block, firstly, you should
* initialize each page (defined in memlayout.h) in this free block. This
* procedure includes:
* - Setting the bit `PG_property` of `p->flags`, which means this page is
* valid. P.S. In function `pmm_init` (in pmm.c), the bit `PG_reserved` of
* `p->flags` is already set.
* - If this page is free and is not the first page of a free block,
* `p->property` should be set to 0.
* - If this page is free and is the first page of a free block, `p->property`
* should be set to be the total number of pages in the block.
* - `p->ref` should be 0, because now `p` is free and has no reference.
* After that, We can use `p->page_link` to link this page into `free_list`.
* (e.g.: `list_add_before(&free_list, &(p->page_link));` )
* Finally, we should update the sum of the free memory blocks: `nr_free += n`.
* (4) `default_alloc_pages`:
* Search for the first free block (block size >= n) in the free list and reszie
* the block found, returning the address of this block as the address required by
* `malloc`.
* (4.1)
* So you should search the free list like this:
* list_entry_t le = &free_list;
* while((le=list_next(le)) != &free_list) {
* ...
* (4.1.1)
* In the while loop, get the struct `page` and check if `p->property`
* (recording the num of free pages in this block) >= n.
* struct Page *p = le2page(le, page_link);
* if(p->property >= n){ ...
* (4.1.2)
* If we find this `p`, it means we've found a free block with its size
* >= n, whose first `n` pages can be malloced. Some flag bits of this page
* should be set as the following: `PG_reserved = 1`, `PG_property = 0`.
* Then, unlink the pages from `free_list`.
* (4.1.2.1)
* If `p->property > n`, we should re-calculate number of the rest
* pages of this free block. (e.g.: `le2page(le,page_link))->property
* = p->property - n;`)
* (4.1.3)
* Re-caluclate `nr_free` (number of the the rest of all free block).
* (4.1.4)
* return `p`.
* (4.2)
* If we can not find a free block with its size >=n, then return NULL.
* (5) `default_free_pages`:
* re-link the pages into the free list, and may merge small free blocks into
* the big ones.
* (5.1)
* According to the base address of the withdrawed blocks, search the free
* list for its correct position (with address from low to high), and insert
* the pages. (May use `list_next`, `le2page`, `list_add_before`)
* (5.2)
* Reset the fields of the pages, such as `p->ref` and `p->flags` (PageProperty)
* (5.3)
* Try to merge blocks at lower or higher addresses. Notice: This should
* change some pages' `p->property` correctly.
*/
free_area_t free_area;

Expand Down
Loading

0 comments on commit 65f5b0b

Please sign in to comment.