|
1 | 1 | # Why choose to port an existing malloc/free lib?
|
2 | 2 |
|
3 |
| ---- |
| 3 | +* malloc/free code is an integral part of the OS. |
| 4 | +By using a trusted and tested library we ensure that we do not introduce any hard to detect bugs. |
| 5 | +* Software reuse is important. If possible always prefer to reuse already written software. |
4 | 6 |
|
5 |
| - If a memory allocator is created we will have to check for errors and debug if any are found . |
6 |
| - A much simpler way would be porting an existing malloc library to the kernel space in the os . |
7 |
| - We can focus on creating the os rather than spending a dedicated amount of time creating a memory allocator and as it is a well tested library we wouldn’t have to debug it. |
8 |
| - Hence porting is fast, scalable, stable and requires less time to implement. |
9 | 7 |
|
10 | 8 | # Describe the hooks that need to be implemented
|
11 | 9 |
|
12 |
| ---- |
| 10 | + Four types of hooks are implemented; two of which are used for page frame allocation and two that are used to handle concurrency. |
13 | 11 |
|
14 |
| - Hooks allow memory managers to request memory in terms of pages from the kernel. |
15 |
| - The page size is a constant of 4096 bytes which is obtained from f_size header file. |
16 |
| - Number of pages required is the parameter accepted by hook. |
17 |
| - Basically four types of hooks are implemented, two of which are used for page allocation and deallocation and two used for critial section. |
18 |
| - Critical section is a piece of code that is implemented here so that the completion of memory operations takes place without interruption of other process. |
| 12 | +1. ```c |
| 13 | + void *alloc_page(size_t pages); |
| 14 | + ``` |
| 15 | + Allocates pages number of page frames and returns a pointer to the beginning of the allocated pages. |
19 | 16 |
|
20 |
| -1. void *alloc_page(size_t pages); |
21 |
| - Takes page size as input parameters , allocates consecutive pages in virtual memory and returns a pointer pointing to the beginning of the group . |
| 17 | +2. ```c |
| 18 | + void free_page(void *start, size_t pages); |
| 19 | + ``` |
| 20 | + Frees pages number of page frames starting from the pointer start. |
22 | 21 |
|
23 |
| -2. void free_page(void *start, size_t pages); |
24 |
| - no of pages to be free and the starting location in memory as input parameters and frees allocated pages in virtual memory. |
| 22 | +3. ```c |
| 23 | + void wait_and_lock_mutex(); |
| 24 | + ``` |
| 25 | + Mutex lock mechanism. |
25 | 26 |
|
26 |
| -3. void wait_and_lock_mutex() ; |
27 |
| - locks the mutex before memory manager executes a memory process of a singe thread entering the critical section . |
28 |
| - We can apply mutex lock simply by disabling all the interrupts or by using spin lock. |
29 |
| - |
30 |
| -4. void unlock_mutex(); |
31 |
| - Mutex is unlocked after memory manager leaves the critical section . |
32 |
| - Unlocking can be done by re-enabling the interrupts or resetting the spin lock. |
| 27 | +4. ```c |
| 28 | + void unlock_mutex(); |
| 29 | + ``` |
| 30 | + Mutex unlock mechanism. |
33 | 31 |
|
34 | 32 | # How are the hooks actually implemented using the existing physical page allocator?
|
35 | 33 |
|
36 |
| ---- |
37 |
| - |
38 | 34 | The page size is obtained from the liballoc_init() function .
|
39 | 35 |
|
40 |
| - 1. For allocation of page we are using : void* liballoc_alloc(size_t n_pages) . |
41 |
| - The number of pages required for allocation is accepted as a input parameter and if the required number of pages is not available while considering all the number of unallocated pages then the function returns a NULL value. |
42 |
| - If the required number of pages are available then memory allocation stats from pointer *start . |
43 |
| - Consecutive pages is allocated till the number of required pages is satisfied .The pointer of the allocated memory is returned. |
| 36 | + 1. `void* liballoc_alloc(size_t n_pages)` simply needs to call get_page() n_pages number of times and return the result of the first call. |
44 | 37 |
|
45 |
| -2. For deallocation of pages we will be using : int liballoc_free(void* start, size_t n_pages) . |
46 |
| - The values returned from void* liballoc_alloc(size_t n_pages) is passed as input parameters into this hook. |
47 |
| - Here we set a starting point to start deallocation of memory .Consecutive pages are being deallocated and added to the free page. |
48 |
| - The number of pages to be deallocated should be given in the formal parameter . |
49 |
| - 0 is returned if the deallocation of pages are successful. |
50 | 38 |
|
51 |
| - 3. For locking of memory data structure we are using : int liballoc_lock() . |
52 |
| - Interrupts are disabled so that other important functions can only be done after memory operation. |
53 |
| - Interrupts are cleared using asm("cli"); and if the lock acquired is successful ,0 is returned . |
| 39 | +2. `void free_page(void *start, size_t pages)` only needs to call free_page() with start, start + page_size, start + 2*page_size, ... |
| 40 | +, start+ pages * page_size as parameters. |
54 | 41 |
|
55 |
| - 4. For unlocking of memory data structure we are using : int liballoc_unlock() . |
56 |
| - Setting back the interrupts are done using asm("sti") command. |
57 |
| - Return 0 if the lock is released successfully. |
| 42 | +3. As far as concurrency is concerned, we only need to ensure that no interrupts occur when `wait_and_lock_mutex()` is called. |
| 43 | + This is easily accomplished by disabling interrupts by clearing the interrupt flag. |
| 44 | + The corresponding `unlock_mutex()` call can then enable the interrupts by setting the interrupt flag. |
0 commit comments