You are on page 1of 19

HO CHI MINH UNIVERSITY OF TECHNOLOGY

FALCUTY OF COMPUTER SCIENCE AND ENGINERRING

OPERATING SYSTEM

Assignment

Simple Operating System

Instructors: Nguyễn Lê Duy Lai


Student: 1952863 – Võ Phạm Hoài Nam
1952745 – Huỳnh Kim Hưng
1953096 – Nguyễn Quốc Việt
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

Contents
1. Scheduler ..................................................................................................................... 2
1.1. Question – Priority Feedback Queue .................................................................. 2
1.2. Result – Gantt Diagrams ................................................................................... 3
1.3. Implementation .................................................................................................. 4
1.3.1. Priority Queue ............................................................................................. 4
1.3.2. Scheduler ..................................................................................................... 5
2. Memory Management .................................................................................................. 6
2.1. Question – Segmentation with Paging ................................................................ 6
2.2. Result – Status of RAM ..................................................................................... 6
2.3. Implementation .................................................................................................11
2.3.1. Find page table from segment .....................................................................11
2.3.2. Map virtual addresses to physical addresses ...............................................12
2.3.3. Memory allocation ......................................................................................12
2.3.4. Deallocating Memory ..................................................................................16
3. Put it all together .......................................................................................................18

1
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

1. Scheduler
1.1. Question – Priority Feedback Queue

QUESTION: What is the advantage of using priority feedback queue in comparison with
other scheduling algorithms you have learned?

The Priority Feedback Queue (PFQ) algorithms uses the ideas of a number of other
algorithms, including Priority Scheduling algorithm– each process has a priority for
execution, Multilevel Queue algorithm – using mutliple queue levels of processes, Round
Robin algorithm – uses quantum time for processes to execute. Here are other algorithms
learned

• First Come – First Serve(FCFS)


• Shortest Job First (SJF)
• Shortest Remaining Time First (SRTF)
• Priority Scheduling (PS)
• Round Robin (RR)
• Multilevel Queue Scheduling (MLQS)
• Multilevel Feedback Queue (MLFQ)

Specifically, the PFQ algorithm uses two (2) queues: ready_queue and run_queue with
the following meanings:

• ready_queue: This queue contains processes with higher execution priority than
the run_queue queue. When the CPU moves to the next slot, it searches for the
process in this queue.
• run_queue: This queue contains processes that are waiting to continue executing
after running out of its slot without completing its process. Processes in this queue
can only continue to the next slot when ready_queue is idle and are moved to the
ready_queue queue to consider the next slot.
• Both queues are priority queues, the priority is based on the priority of the process
in the queue.

Advantage of PFQ algorithm


Using time slot, with the idea of RR algorithm with a quantum time interval, creating
fairness in terms of execution time between processes, avoid CPU usage, delay indefinitely.

Using 2 queues, with the idea of MLQS and MLFQ algorithms, in which 2 queues are
switched between processes until the process is completed, increasing the response time
2
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

for processes. (lower-priority processes that come later can still be executed before higher-
priority processes after they have finished their slots).

Fairness between processes is guaranteed, only depending on the available priority of the
processes. Specifically, in a certain time interval t0, if processes are executing, it
completely depends on their priority. If another process p0 enters the priority queue and
depends on its priority, even though the other processes with higher priority have finished
executing before. They also cannot dispute with process p0 because they are waiting in
run_queue until ready_queue is idle, i.e. p0 has been executing its slot.

1.2. Result – Gantt Diagrams

REQUIREMENT: Draw Gantt diagram describing how processes are executed by the
CPU

Below is the Gantt diagram for the case in the source code.

*(Evidence in the folder log/sched.txt)

Test 0:

Image 1: Gantt CPU diagram executing processes – Test 0

In this test, CPU processes on 2 processes S0 and S1 in 22 time slots as above Gantt
diagram

Test 1:

Image 2: Gantt CPU diagram executing processes – Test 1

3
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

In this test, CPU processes on 4 processes S0, S1, S2 and S3 in 43 time slots as above
Gantt diagram

1.3. Implementation
1.3.1. Priority Queue
The priorit queue in this case handles no more than 10 processes, so we simply need to
use the loop to handle the functionality a priority queue needs. Specifically with the
enqueue() function, we only need to put it at the end of the queue if it is available
(empty). With the dequeue() function, we browse for the process with the highest
priority, and update the queue’s state when deleting an element.

Below is the priority queue implementation for Scheduler.

int empty(struct queue_t *q)


{
return (q->size == 0);
}

void enqueue(struct queue_t *q, struct pcb_t *proc)


{
int idx = 0;
while (idx != q->size && q->proc[idx]->priority > proc->priority) {
idx++;
}
if (idx != q->size){
for (int i = q->size; i != idx; i--){
q->proc[i] = q->proc[i - 1];
}
}
q->proc[idx] = proc;
q->size = q->size + 1;
}

struct pcb_t *dequeue(struct queue_t *q)


{
struct pcb_t *proc = NULL;
if (q->size > 0){
proc = q->proc[0];
for (int i = 0; i < q->size - 1; i++){
q->proc[i] = q->proc[i + 1];
}
q->proc[q->size - 1] = NULL;
free(q->proc[q->size - 1]);
q->size = q->size - 1;

4
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

}
return proc;
}

1.3.2. Scheduler
The task of the scheduler is to manage the updating of the processes that will be executed
to the CPU. Specifically, the scheduler will manage 2 ready_queue and run_queue as
described above. In this assignment, we just need to implement the function to find a
process for the CPU to execute. Specifically, with the get_proc() function which returns
a process in the ready_queue, if the ready_queue is idle, we update the queue with
processes that are waiting for the next slots in the run_queue. On the contrary, we find
the processes with high priority from this queue.

Here is the implementation of the above function

struct pcb_t *get_proc(void)


{
struct pcb_t *proc = NULL;

pthread_mutex_lock(&queue_lock);
if (!empty(&ready_queue))
{
proc = dequeue(&ready_queue);
}
else
{
int i;
for (i = 0; i < run_queue.size; i++)
{
enqueue(&ready_queue, run_queue.proc[i]);
}
ready_queue.size = run_queue.size;
for (i = 0; i < run_queue.size; i++)
{
run_queue.proc[i] = NULL;
}
run_queue.size = 0;
proc = dequeue(&ready_queue);
}
pthread_mutex_unlock(&queue_lock);
return proc;
}

5
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

2. Memory Management
2.1. Question – Segmentation with Paging
QUESTION: What is the advantage and disadvantage of segmentation with paging?

Advantage

• Save memory, use memory efficiently.


• Having the advantage of paging algorithms:
o Simplify memory allocation
o Fixed foreign fragmentation
• Solve the problem of external fragmentation of the segmentation algorithm by
paging in each segment.

Disadvantage

• The internal fragmentation of the paging algorithm is still present.

2.2. Result – Status of RAM


REQUIREMENT: Show the status of RAM after each memory allocation and
deallocation function call.

Below are the results of the logging process after each allocation and deallocation
function call in the program, specifically recording the state of RAM in the program at
each step.

------ MEMORY MANAGEMENT TEST 0 ------------------------------------


./mem input/proc/m0
=======Allocation=======
000: 00000-003ff - PID: 01 (idx 000, nxt: 001)
001: 00400-007ff - PID: 01 (idx 001, nxt: 002)
002: 00800-00bff - PID: 01 (idx 002, nxt: 003)
003: 00c00-00fff - PID: 01 (idx 003, nxt: 004)
004: 01000-013ff - PID: 01 (idx 004, nxt: 005)
005: 01400-017ff - PID: 01 (idx 005, nxt: 006)
006: 01800-01bff - PID: 01 (idx 006, nxt: 007)
007: 01c00-01fff - PID: 01 (idx 007, nxt: 008)

6
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

008: 02000-023ff - PID: 01 (idx 008, nxt: 009)


009: 02400-027ff - PID: 01 (idx 009, nxt: 010)
010: 02800-02bff - PID: 01 (idx 010, nxt: 011)
011: 02c00-02fff - PID: 01 (idx 011, nxt: 012)
012: 03000-033ff - PID: 01 (idx 012, nxt: 013)
013: 03400-037ff - PID: 01 (idx 013, nxt: -01)
=======Allocation=======
000: 00000-003ff - PID: 01 (idx 000, nxt: 001)
001: 00400-007ff - PID: 01 (idx 001, nxt: 002)
002: 00800-00bff - PID: 01 (idx 002, nxt: 003)
003: 00c00-00fff - PID: 01 (idx 003, nxt: 004)
004: 01000-013ff - PID: 01 (idx 004, nxt: 005)
005: 01400-017ff - PID: 01 (idx 005, nxt: 006)
006: 01800-01bff - PID: 01 (idx 006, nxt: 007)
007: 01c00-01fff - PID: 01 (idx 007, nxt: 008)
008: 02000-023ff - PID: 01 (idx 008, nxt: 009)
009: 02400-027ff - PID: 01 (idx 009, nxt: 010)
010: 02800-02bff - PID: 01 (idx 010, nxt: 011)
011: 02c00-02fff - PID: 01 (idx 011, nxt: 012)
012: 03000-033ff - PID: 01 (idx 012, nxt: 013)
013: 03400-037ff - PID: 01 (idx 013, nxt: -01)
014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
=======Deallocation=======
014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
=======Allocation=======
000: 00000-003ff - PID: 01 (idx 000, nxt: 001)

7
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

001: 00400-007ff - PID: 01 (idx 001, nxt: -01)


014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
=======Allocation=======
000: 00000-003ff - PID: 01 (idx 000, nxt: 001)
001: 00400-007ff - PID: 01 (idx 001, nxt: -01)
002: 00800-00bff - PID: 01 (idx 000, nxt: 003)
003: 00c00-00fff - PID: 01 (idx 001, nxt: 004)
004: 01000-013ff - PID: 01 (idx 002, nxt: 005)
005: 01400-017ff - PID: 01 (idx 003, nxt: 006)
006: 01800-01bff - PID: 01 (idx 004, nxt: -01)
014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
000: 00000-003ff - PID: 01 (idx 000, nxt: 001)
003e8: 14
001: 00400-007ff - PID: 01 (idx 001, nxt: -01)
002: 00800-00bff - PID: 01 (idx 000, nxt: 003)
003: 00c00-00fff - PID: 01 (idx 001, nxt: 004)
004: 01000-013ff - PID: 01 (idx 002, nxt: 005)
005: 01400-017ff - PID: 01 (idx 003, nxt: 006)
006: 01800-01bff - PID: 01 (idx 004, nxt: -01)
014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
03814: 64
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
------ MEMORY MANAGEMENT TEST 1 ------------------------------------
./mem input/proc/m1
=======Allocation=======
000: 00000-003ff - PID: 01 (idx 000, nxt: 001)

8
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

001: 00400-007ff - PID: 01 (idx 001, nxt: 002)


002: 00800-00bff - PID: 01 (idx 002, nxt: 003)
003: 00c00-00fff - PID: 01 (idx 003, nxt: 004)
004: 01000-013ff - PID: 01 (idx 004, nxt: 005)
005: 01400-017ff - PID: 01 (idx 005, nxt: 006)
006: 01800-01bff - PID: 01 (idx 006, nxt: 007)
007: 01c00-01fff - PID: 01 (idx 007, nxt: 008)
008: 02000-023ff - PID: 01 (idx 008, nxt: 009)
009: 02400-027ff - PID: 01 (idx 009, nxt: 010)
010: 02800-02bff - PID: 01 (idx 010, nxt: 011)
011: 02c00-02fff - PID: 01 (idx 011, nxt: 012)
012: 03000-033ff - PID: 01 (idx 012, nxt: 013)
013: 03400-037ff - PID: 01 (idx 013, nxt: -01)
=======Allocation=======
000: 00000-003ff - PID: 01 (idx 000, nxt: 001)
001: 00400-007ff - PID: 01 (idx 001, nxt: 002)
002: 00800-00bff - PID: 01 (idx 002, nxt: 003)
003: 00c00-00fff - PID: 01 (idx 003, nxt: 004)
004: 01000-013ff - PID: 01 (idx 004, nxt: 005)
005: 01400-017ff - PID: 01 (idx 005, nxt: 006)
006: 01800-01bff - PID: 01 (idx 006, nxt: 007)
007: 01c00-01fff - PID: 01 (idx 007, nxt: 008)
008: 02000-023ff - PID: 01 (idx 008, nxt: 009)
009: 02400-027ff - PID: 01 (idx 009, nxt: 010)
010: 02800-02bff - PID: 01 (idx 010, nxt: 011)
011: 02c00-02fff - PID: 01 (idx 011, nxt: 012)
012: 03000-033ff - PID: 01 (idx 012, nxt: 013)
013: 03400-037ff - PID: 01 (idx 013, nxt: -01)

9
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

014: 03800-03bff - PID: 01 (idx 000, nxt: 015)


015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
=======Deallocation=======
014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
=======Allocation=======
000: 00000-003ff - PID: 01 (idx 000, nxt: 001)
001: 00400-007ff - PID: 01 (idx 001, nxt: -01)
014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
=======Allocation=======
000: 00000-003ff - PID: 01 (idx 000, nxt: 001)
001: 00400-007ff - PID: 01 (idx 001, nxt: -01)
002: 00800-00bff - PID: 01 (idx 000, nxt: 003)
003: 00c00-00fff - PID: 01 (idx 001, nxt: 004)
004: 01000-013ff - PID: 01 (idx 002, nxt: 005)
005: 01400-017ff - PID: 01 (idx 003, nxt: 006)
006: 01800-01bff - PID: 01 (idx 004, nxt: -01)
014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
=======Deallocation=======
002: 00800-00bff - PID: 01 (idx 000, nxt: 003)
003: 00c00-00fff - PID: 01 (idx 001, nxt: 004)
004: 01000-013ff - PID: 01 (idx 002, nxt: 005)
005: 01400-017ff - PID: 01 (idx 003, nxt: 006)
006: 01800-01bff - PID: 01 (idx 004, nxt: -01)
014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)

10
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

=======Deallocation=======
014: 03800-03bff - PID: 01 (idx 000, nxt: 015)
015: 03c00-03fff - PID: 01 (idx 001, nxt: -01)
*NOTE: In order to show the allocation and deallocation function call, we add another
dump() function at the end of alloc_mem() and free_mem() function, right before
pthread_mutex_unlock(&mem_lock);.
If you want to see the result above in the terminal, please uncomment those code lines
in the mem.c file.

2.3. Implementation
2.3.1. Find page table from segment
In this assignment, each address is represented by 20 bits, where the first 5 bits represent
the segment index, the next 5 bits represent the page index, and the last 10 bits represent
the offset.

This function takes the 5 bit segment index and the seg_table, needs to find the res
of the paging table of the corresponding segment in the above segment table.

Since the seg_table fragment table is a structured list of u elements (v_index,


page_table_t), where v_index is the 5 bit segment of element u and page_table_t is
the corresponding page part table of that segment. So to find res, we just need to traverse
this segment table, which element u has v_index equals to the index we want to find,
we return the corresponding page_table.

Below is the implementation for the above function.

static struct page_table_t * get_page_table


(addr_t index, struct seg_table_t * seg_table) {

int i;
for (i = 0; i < seg_table->size; i++) {

if (index == seg_table->table[i].v_index){
return seg_table->table[i].pages;
}
}
return NULL;

11
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

2.3.2. Map virtual addresses to physical addresses


Because each address consists of 20 bits with the same organization as mentioned above,
so to create a physical address, we take the first 10 bits (segment and page) and connect
the last 10 bits (offset). Each page_table_t stores element with a p_index of the first
10 bits. So to create a physical address, we jusst need to shift left those 10 bits by 10 bits
offset and or (||) these 2 strings.

Here is the implementation of the above function

static int translate(


addr_t virtual_addr,
addr_t * physical_addr,
struct pcb_t * proc) {

addr_t offset = get_offset(virtual_addr);

addr_t first_lv = get_first_lv(virtual_addr);

addr_t second_lv = get_second_lv(virtual_addr);

struct page_table_t * page_table = NULL;


page_table = get_page_table(first_lv, proc->seg_table);
if (page_table == NULL) {
return 0;
}

int i;
for (i = 0; i < page_table->size; i++) {
if (page_table->table[i].v_index == second_lv) {
*physical_addr = offset +
(page_table->table[i].p_index << OFFSET_LEN);
return 1;
}
}
return 0;
}

2.3.3. Memory allocation


2.3.3.1. Check available memory
In this step, we check if memory is available both on the physical and logical memory.

On the physical area, we check the number of empty pages, not yet used by any process,
if enough pages need to be allocated, the physical area is ready. In addition, to optimize
the search time when falling into the case of insufficient memory, we can organize

12
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

mem_stat in the form of a list, including size management, free memory,… to access
needed information quickly.

On the logical memory area, we check based on the break point of the process, not
exceeding the allowed memory area.

int mem_avail = 0;
int count_free_page = 0;
int i;
for (i = 0; i < NUM_PAGES; i++)
{
if (_mem_stat[i].proc == 0) {
count_free_page++;
}
}

if (count_free_page >= num_pages && (proc->bp + num_pages *


PAGE_SIZE <= (1 << ADDRESS_SIZE)))
mem_avail = 1;

2.3.3.2. Allocate memory


If mem_avail equals 1, we do the following steps:

• Browse the physical memory, find idle pages, assign this page to be used by the
process.
• Create variable prev_page to update next value easier.
• On the logical memory area, based on the allocated address, counting from the
start address and the page order position, we find its segments and pages. From
there we update corresponding paging and segment tables.

Below is the full implementation of the alloc_mem function (including checking


available memory)
addr_t alloc_mem(uint32_t size, struct pcb_t * proc) {
pthread_mutex_lock(&mem_lock);
addr_t ret_mem = 0;
/* TODO: Allocate [size] byte in the memory for the
* process [proc] and save the address of the first
* byte in the allocated memory region to [ret_mem].
* */

uint32_t num_pages = ((size % PAGE_SIZE) == 0) ? size / PAGE_SIZE : size / PAGE_SIZE


+ 1; // Number of pages we will use
int mem_avail = 0; // We could allocate new memory region or not?
//printf("\n\n%d\n\n", num_pages);
/* First we must check if the amount of free memory in

13
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

* virtual address space and physical address space is


* large enough to represent the amount of required
* memory. If so, set 1 to [mem_avail].
* Hint: check [proc] bit in each page of _mem_stat
* to know whether this page has been used by a process.
* For virtual memory space, check bp (break pointer).
* */

// Check free memory in physical memory space


int count_free_page = 0;
int i;
for (i = 0; i < NUM_PAGES; i++)
{
if (_mem_stat[i].proc == 0) {
count_free_page++;
}
}

// Space is free must >= num_pages need


// Used breakpoint + size need to allocate must <= the size of virtual memory
if (count_free_page >= num_pages && (proc->bp + num_pages * PAGE_SIZE <= (1 <<
ADDRESS_SIZE)))
mem_avail = 1;

if (mem_avail==1) {
/* We could allocate new memory region to the process */
ret_mem = proc->bp;
proc->bp += num_pages * PAGE_SIZE;
/* Update status of physical pages which will be allocated
* to [proc] in _mem_stat. Tasks to do:
* - Update [proc], [index], and [next] field
* - Add entries to segment table page tables of [proc]
* to ensure accesses to allocated memory slot is
* valid. */

// Virtual address (vir_addr) to calculate segment index


// Update index counter (up_idx_count) to update the index field in _mem_stat
// Segment index (seg_idx) is calculated by virtual address and update the
segment table
// Previous page (prev_page) to stored the previous page as we can not know
exactly the next free page in the _mem_stat

// Initializing ...
addr_t vir_addr = ret_mem;
int up_idx_count = 0;
int seg_idx = -1;
int page_idx = -1;
int prev_page = -1;

// Traversing to find the free _mem_stat (proc->pid = 0)


for (i = 0; i < NUM_PAGES; i++)
{
// Updating the free _mem_stat with the pid, index, next
if (_mem_stat[i].proc == 0) {
// Update the proc of _mem_stat by the pid of process
// Update index increase by 1 every time a process take the free
_mem_stat
_mem_stat[i].proc = proc->pid;

14
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

_mem_stat[i].index = up_idx_count++;
// If prev_page is not the initial value (!= -1) we will update the
previous _mem_stat's next field
if (prev_page != -1) {
_mem_stat[prev_page].next = i;
}
prev_page = i;

// Calculate the segment index and updating the table for index
seg_idx = get_first_lv(vir_addr);
// Finding the position in the segment table that has the v_index ==
seg_idx
// Check whether found or not, if not found that means this is a new
segment to the table
// So we need to increase the size of segment table by 1
int position;
int found = 0;
for (position = 0; position < proc->seg_table->size; position++) {
if (seg_idx == proc->seg_table->table[position].v_index) {
found = 1;
break;
}
}
if (found == 0) {
proc->seg_table->size++;
}
// If the pages are not there yet, we must allocate the pages
if (proc->seg_table->table[position].pages == NULL) {
proc->seg_table->table[position].pages
= (struct page_table_t *)malloc(sizeof(struct page_table_t));
proc->seg_table->table[position].pages->size = 0;
}
// To make the virtual memory to be contiguous, we must allocate the new
page right after the last page
// For example, the size of the page table is 5, that means we have the
pages 0, 1, 2, 3, 4
// The new page to be allocate will be 5, exactly the size of pages table
// The codes below show the assignment of pages table and increment of
the pages table size
// v_index of the table will be the second level of virtual address take
by get_second_lv(vir_addr)
// p_index exactly the i in the loop
// The virtual address we have is ( 5 | 5 | 10 ) for first level, second,
offset respectively
// The physical address we have will is (10 | 10) for the position in
_mem_stat (i) and offset from virtual address
page_idx = proc->seg_table->table[position].pages->size;
proc->seg_table->table[position].v_index = seg_idx;
proc->seg_table->table[position].pages->table[page_idx].v_index
= get_second_lv(vir_addr);
proc->seg_table->table[position].pages->table[page_idx].p_index = i;
proc->seg_table->table[position].pages->size++;
// The virtual address increase to be used in the next loop
vir_addr += PAGE_SIZE;
// Now that the number of page we have allocate is equal to num_pages,
the next field of our will be -1 and step out the loops
if (up_idx_count == num_pages) {
_mem_stat[i].next = -1;

15
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

break;
}
}

}
}
//Uncomment code below to show the allocation process
/*
printf("========Allocation==========");
dump();
*/
pthread_mutex_unlock(&mem_lock);
return ret_mem;
}

2.3.4. Deallocating Memory


In order to deallocating memory, we do the following steps:

• Convert logical address from the process to the physical, the based on the value
next of mem, we update the corresponding address string
• Based on the number of deleted pages on the block of the physical address, we find
the pages of the logical address in turn, based on the address, we find the
corresponding segment and page. Then update the paging table again, after the
update process, if the table is empty, delete this table in the segment
• Only when the last block on the logical address is deleted, then from there cycle
back through the pages, until the page is being used, then stop

Below is the detailed implementation


int free_mem(addr_t address, struct pcb_t * proc) {
/*TODO: Release memory region allocated by [proc]. The first byte of
* this region is indicated by [address]. Task to do:
* - Set flag [proc] of physical page use by the memory block
* back to zero to indicate that it is free.
* - Remove unused entries in segment table and page tables of
* the process [proc].
* - Remember to use lock to protect the memory from other
* processes. */
pthread_mutex_lock(&mem_lock);
addr_t vir_addr = address;// Take the beginning virtual address to start freeing
addr_t phy_addr; // Physical address to calculate the physcial page
addr_t phy_page; // Physical page to modify the _mem_stat
int i;
int n;
// Check if the address is there and can be free
int flag = translate(address, &phy_addr, proc);
if (flag == 1) {
// Shift to get the physical page address
phy_page = phy_addr >> OFFSET_LEN;

addr_t seg_idx; // Segment index of the segment table

while (phy_page != -1) {

16
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

// Set back flag [proc] to 0 to indicate it is free


_mem_stat[phy_page].proc = 0;
// Calculate the segment index
seg_idx = get_first_lv(vir_addr);
// Modify the pages table
for (i = 0; i < proc->seg_table->table[seg_idx].pages->size; i++) {
if (proc->seg_table->table[seg_idx].pages->table[i].p_index == phy_page)
{
// Decrease the size of pages table as we free the page
n = --proc->seg_table->table[seg_idx].pages->size;
// The v_index at i will change to the v_index at the old size - 1
as we don't care the last value anymore
// Same happen with p_index
proc->seg_table->table[seg_idx].pages->table[i].v_index
= proc->seg_table->table[seg_idx].pages->table[n].v_index;
proc->seg_table->table[seg_idx].pages->table[i].p_index
= proc->seg_table->table[seg_idx].pages->table[n].p_index;
}
}
// Increment of virtual address for using in the loop
vir_addr += PAGE_SIZE;
// Find the next physical page to free
phy_page = _mem_stat[phy_page].next;
}
}
//Uncomment code below to show the deallocation process
/*
printf("========Deallocation==========");
dump();
*/
pthread_mutex_unlock(&mem_lock);
return 0;
}

17
Ho Chi Minh University of Technology - Faculty of Computer Science & Engineering

3. Put it all together


After we combine scheduling and memory, we using make os and make all and have the
outcome in the log/os.txt folder

This is the Gantt diagram in the case of make all

Test 0:

Image 3: OS CPU diagram executing processes – Test 0

Test 1:

Image 4: OS CPU diagram executing processes – Test 1

18

You might also like