Operating system (software engineer), Lecture notes of Operating Systems

Operating system Computer science

Typology: Lecture notes

2022/2023

Available from 03/21/2025

ismail-ibrahim-7
ismail-ibrahim-7 🇬🇧

1 document

1 / 78

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
EE442 Operating Systems Ch.1 Introduction to OS
Lecture Notes by Ugur Halıcı 1
Chapter 1
Introduction to Operating Systems
1.1 General Definition
An OS is a program which acts as an interface between computer system users and the
computer hardware. It provides a user-friendly environment in which a user may easily
develop and execute programs. Otherwise, hardware knowledge would be mandatory for
computer programming. So, it can be said that an OS hides the complexity of hardware from
uninterested users.
In general, a computer system has some resources which may be utilized to solve a
problem. They are
Memory
Processor(s)
I/O
File System
etc.
The OS manages these resources and allocates them to specific programs and users. With
the management of the OS, a programmer is rid of difficult hardware considerations. An OS
provides services for
Processor Management
Memory Management
File Management
Device Management
Concurrency Control
Another aspect for the usage of OS is that; it is used as a predefined library for hardware-
software interaction and this is why, system programs apply to the installed OS since they
cannot reach hardware directly.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f
pf40
pf41
pf42
pf43
pf44
pf45
pf46
pf47
pf48
pf49
pf4a
pf4b
pf4c
pf4d
pf4e

Partial preview of the text

Download Operating system (software engineer) and more Lecture notes Operating Systems in PDF only on Docsity!

EE442 Operating Systems Ch.1 Introduction to OS

Lecture Notes by Ugur Halıcı 1

Chapter 1

Introduction to Operating Systems

1.1 General Definition

An OS is a program which acts as an interface between computer system users and the computer hardware. It provides a user-friendly environment in which a user may easily develop and execute programs. Otherwise, hardware knowledge would be mandatory for computer programming. So, it can be said that an OS hides the complexity of hardware from uninterested users.

In general, a computer system has some resources which may be utilized to solve a problem. They are

  • Memory
  • Processor(s)
  • I/O
  • File System etc.

The OS manages these resources and allocates them to specific programs and users. With the management of the OS, a programmer is rid of difficult hardware considerations. An OS provides services for

  • Processor Management
  • Memory Management
  • File Management
  • Device Management
  • Concurrency Control

Another aspect for the usage of OS is that; it is used as a predefined library for hardware- software interaction and this is why, system programs apply to the installed OS since they cannot reach hardware directly.

EE442 Operating Systems Ch.1 Introduction to OS

Lecture Notes by Ugur Halıcı 2

With the advantage of easier programming provided by the OS, the hardware, its machine language and the OS constitutes a new combination called as a virtual (extended) machine.

In a more simplistic approach, in fact, OS itself is a program. But it has a priority which application programs don’t have. OS uses the kernel mode of the microprocessor, whereas other programs use the user mode. The difference between two is that; all hardware instructions are valid in kernel mode, where some of them cannot be used in the user mode.

Application Programs

System Programs

Operating System

Machine Language

HARDWARE

Since we have an already written library, namely the OS, to add two numbers we simply write the following line to our program: c = a + b ; whereas in a system where there is no OS installed, we should consider some hardware work as:

(Assuming an MC 6800 computer hardware)

LDAA $80 Æ Loading the number at memory location 80 LDAB $81 Æ Loading the number at memory location 81 ADDB Æ Adding these two numbers STAA $55 Æ Storing the sum to memory location 55

As seen, we considered memory locations and used our hardware knowledge of the system.

In an OS installed machine, since we have an intermediate layer, our programs obtain some advantage of mobility by not dealing with hardware. For example, the above program segment would not work for an 8086 machine, where as the “c = a + b ;” syntax will be suitable for both.

A simple program segment with no hardware consideration

A more sophisticated program segment with hardware consideration

Hardware

OS response

Machine Language

Machine Language

Hardware

Machine Language

Hardware

Operating System

Machine

Virtual (Extended) Machine

EE442 Operating Systems Ch.1 Introduction to OS

Lecture Notes by Ugur Halıcı 4

Use of the networks required OSs appropriate for them. In network systems , each process runs in its own machine. The OS can access to other machines. By this way, file sharing, messaging, etc. became possible.In networks, users are aware of the fact that s/he is working in a network and when information is exchanged. The user explicitly handles the transfer of information.

Distributed systems are similar to networks. However in such systems, there is no need to exchange information explicitly, it is handled by the OS itself whenever necessary.

With continuing innovations, new architectures and compatible OSs are developed. But their details are not in the scope of this text since the objective here is to give only a general view about developments in OS concept.

Each is a computer having its own CPU, RAM, etc. An OS supporting networks is installed on them.

EE442 Operating Systems Ch. 2 Process Scheduling

Chapter 2

Processor Scheduling

2.1 Processes

A process is an executing program, including the current values of the program counter, registers, and variables.The subtle difference between a process and a program is that the program is a group of instructions whereas the process is the activity.

In multiprogramming systems, processes are performed in a pseudoparallelism as if each process has its own processor. In fact, there is only one processor but it switches back and forth from process to process.

Henceforth, by saying execution of a process, we mean the processor’s operations on the process like changing its variables, etc. and I/O work means the interaction of the process with the I/O operations like reading something or writing to somewhere. They may also be named as “processor (CPU) burst” and “I/O burst” respectively. According to these definitions, we classify programs as

  • Processor-bound program : A program having long processor bursts (execution instants).
  • I/O-bound program : A program having short processor bursts.

Assume we have two processes A and B. Both execute for 1 second and do some I/O work for 1 second. This pattern is repeated 3 times for process A and 2 times for process B. . If we have no multiprogramming , the processes are executed sequentially as below.

Time

Exec (^) A1 I/OA1 Exec (^) A2 I/OA2 Exec (^) A3 I/OA3 Exec (^) B1 I/OB1 Exec (^) B2 I/OB

So, the processor executes these two processes in a total time of 10 seconds. However, it is idle at I/O instants of processes. So, it is idle for 5 seconds and utilized for 5 seconds.

Then the processor utilization is 100 50 %

u

Now let’s consider multiprogramming case:

CPU A1 B1 A2 B2 A3 Idle

I/0 idle A1 B1 A2 B2 A

A enters

A leaves B leaves

B enters

A enters (^) B enters B leaves A leaves

EE442 Operating Systems Ch. 2 Process Scheduling

2.3 Scheduler

If we consider batch systems, there will often be more processes submitted than the number of processes that can be executed immediately. So incoming processes are spooled (to a disk). The long-term scheduler selects processes from this process pool and loads selected processes into memory for execution.

The short-term scheduler selects the process to get the processor from among the processes which are already in memory.

The short-time scheduler will be executing frequently (mostly at least once every 10 milliseconds). So it has to be very fast in order to achieve a better processor utilization. The short-time scheduler, like all other OS programs, has to execute on the processor. If it takes 1 millisecond to choose a process that means ( 1 / ( 10 + 1 )) = 9% of the processor time is being used for short time scheduling and only 91% may be used by processes for execution.

The long-term scheduler on the other hand executes much less frequently. It controls the degree of multiprogramming (no. of processes in memory at a time). If the degree of multiprogramming is to be kept stable (say 10 processes at a time), then the long-term scheduler may only need to be invoked when a process finishes execution.

The long-term scheduler must select a good process mix of I/O-bound and processor bound processes. If most of the processes selected are I/O-bound, then the ready queue will almost be empty while the device queue(s) will be very crowded. If most of the processes are processor-bound, then the device queue(s) will almost be empty while the ready queue is very crowded and that will cause the short-term scheduler to be invoked very frequently.

Time-sharing systems (mostly) have no long-term scheduler. The stability of these systems either depends upon a physical limitation (no. of available terminals) or the self-adjusting nature of users (if you can't get response, you quit).

It can sometimes be good to reduce the degree of multiprogramming by removing processes from memory and storing them on disk. These processes can then be reintroduced into memory by the medium-term scheduler. This operation is also known as swapping. Swapping may be necessary to improve the process mix or to free memory.

2.4. Performance Criteria

In order to achieve an efficient processor management, OS tries to select the most appropriate process from the ready queue. For selection, the relative importance of the followings may be considered as performance criteria.

Execution of A

Save PCA Save REGISTERS (^) A Load PCB Load REGISTERS (^) B (^) Execution of B

Execution of A

Save PCB Save REGISTERS (^) B Load PCA Load REGISTERS (^) A

(Context Switching)

EE442 Operating Systems Ch. 2 Process Scheduling

Processor Utilization: The ratio of busy time of the processor to the total time passes for processes to finish. We would like to keep the processor as busy as possible.

Processor Utilization = (Processor buy time) / (Processor busy time + Processor idle time)

Throughput: The measure of work done in a unit time interval.

Throughput = (Number of processes completed) / (Time Unit)

Turnaround Time (tat): The sum of time spent waiting to get into the ready queue, execution time and I/O time.

tat = t(process completed) – t(process submitted)

Waiting Time (wt): Time spent in ready queue. Processor scheduling algorithms only affect the time spent waiting in the ready queue. So, considering only waiting time instead of turnaround time is generally sufficient.

Response Time (rt): The amount of time it takes to start responding to a request. This criterion is important for interactive systems.

rt = t(first response) – t(submission of request)

We, normally, want to maximize the processor utilization and throughput, and minimize tat, wt, and rt. However, sometimes other combinations may be required depending on to processes.

2.5 Processor Scheduling algorithms

Now, let’s discuss some processor scheduling algorithms again stating that the goal is to select the most appropriate process in the ready queue. For the sake of simplicity, we will assume that we have a single I/O server and a single device queue, and we will assume our device queue always implemented with FIFO method. We will also neglect the switching time between processors ( context switching ).

2.3.1 First-Come-First-Served (FCFS)

In this algorithm, the process to be selected is the process which requests the processor first. This is the process whose PCB is at the head of the ready queue. Contrary to its simplicity, its performance may often be poor compared to other algorithms.

FCFS may cause processes with short processor bursts to wait for a long time. If one process with a long processor burst gets the processor, all the others will wait for it to release it and the ready queue will be filled very much. This is called the convoy effect.

Example 2.

Consider the following information and draw the timing (Gannt) chart for the processor and the I/O server using FCFS algorithm for processor scheduling.

EE442 Operating Systems Ch. 2 Process Scheduling

Example 2.2 :

Consider the same process table in Example 2.1 and draw the timing charts of the processor and I/O assuming SPF is used for processor scheduling. (Assume FCFS for I/0)

A B C D C D B A

CPU (^) A1 C1 B1 D1 C2 D2 A2 D3 B2 A 0 2 3 4 6 14 15 17 18 22 23 31 35

I/O (^) A1 C1 B1D1 D2 A 0 4 8 9 14 15 16 18 19 22 26 35

Processor utilization = (35 / 35) * 100 = 100 %

Throughput = 4 / 35 = 0.

tat (^) A = 35 – 0 = 35 tat (^) B = 31 – 2 = 29 tat (^) C = 17 – 3 = tat (^) D = 23 – 7 = 16

tat (^) AVG = (35 + 29 + 15 + 16) / 4 = 23.

wt (^) A = (0 – 0) + (18 – 8) + (31 – 26) = 15 wt (^) B = (6 – 2) + (23 – 15) = 12 wt (^) C = (4 – 3) + (15 – 9) = 7 wt (^) D = (14 – 7) + (17 – 16) + (22 – 19) = 11

wt (^) AVG = (15 + 12 + 7 + 11) / 4 = 11.

rt (^) A = 0 – 0 = 0 rt (^) B = 6 – 2 = 4 rt (^) C = 4 – 3 = 1 rt (^) D = 14 – 7 = 7

rt (^) AVG = (0 + 4 + 1 + 7) / 4 = 3

2.3.3 Shortest-Remaining-Time-First (SRTF)

The scheduling algorithms we discussed so far are all non-preemptive algorithms. That is, once a process grabs the processor, it keeps the processor until it terminates or it requests I/O.

To deal with this problem (if so), preemptive algorithms are developed. In this type of algorithms, at some time instant, the process being executed may be preempted to execute a new selected process. The preemption conditions are up to the algorithm design.

SPF algorithm can be modified to be preemptive. Assume while one process is executing on the processor, another process arrives. The new process may have a predicted next processor burst time shorter than what is left of the currently executing process. If the SPF algorithm is preemptive, the currently executing process will be preempted from the

EE442 Operating Systems Ch. 2 Process Scheduling

processor and the new process will start executing. The modified SPF algorithm is named as Shortest-Remaining-Time-First (SRTF) algorithm.

Example 2.

Consider the same process table in Example 2.1 and draw the timing charts of the processor and I/O assuming SRTF is used for processor scheduling.

A B C D C D A B

CPU (^) A1 C1 B1 D1 A2 C2 D2A2D3 A2 B1 A3 B 0 2 3 4 6 7 8 9 11 12 13 14 16 23 27 35

I/O A1 C1 D1 D2 A2 B 0 4 8 9 10 12 13 16 20 23 24 35

Processor utilization = (35 / 35) * 100 = 100 %

Throughput = 4 / 35 = 0.

tat (^) A = 27 – 0 = 27 tat (^) B = 35 – 2 = 33 tat (^) C = 11 – 3 = 8 tat (^) D = 14 – 7 = 7

tat (^) AVG = (27 + 33 + 8 + 7) / 4 = 18.

wt (^) A = (0 – 0) + (8 – 8) + (12 - 9) + (14 – 13) + (23 - 20) = 7 wt (^) B = (6 – 2) + (16 – 7) + (27-24) = 16 wt (^) C = (4 – 3) + (9 – 9) = 1 wt (^) D = (7 – 7) + (11 – 10) + (13 – 13) = 1

wt (^) AVG = (7 + 16 + 1 + 1) / 4 = 6.

rt (^) A = 0 – 0 = 0 rt (^) B = 6 – 2 = 4 rt (^) C = 4 – 3 = 1 rt (^) D = 7 – 7 = 0

rt (^) AVG = (0 + 4 + 1 + 0) / 4 = 1.

2.3.4 Round-Robin Scheduling (RRS)

In RRS algorithm the ready queue is treated as a FIFO circular queue. The RRS traces the ready queue allocating the processor to each process for a time interval which is smaller than or equal to a predefined time called time quantum (slice).

The OS using RRS, takes the first process from the ready queue, sets a timer to interrupt after one time quantum and gives the processor to that process. If the process has a processor burst time smaller than the time quantum, then it releases the processor

EE442 Operating Systems Ch. 2 Process Scheduling

FCFS SPF SRT RR tat (^) avg 28.25 23.5 18.75 24. wt (^) avg 16.5 10.5 6.25 12. rt (^) avg 4.5 3 1.25 2. Easy to implement Not possible to know next CPU burst exactly, it can only be guessed

Not possible to know next CPU burst exactly, it can only be guessed

Implementable, rt (^) max is important for interactive systems

2.3.5 Priority Scheduling

In this type of algorithms a priority is associated with each process and the processor is given to the process with the highest priority. Equal priority processes are scheduled with FCFS method.

To illustrate, SPF is a special case of priority scheduling algorithm where

Priority(i) = 1 / next processor burst time of process i

Priorities can be fixed externally or they may be calculated by the OS from time to time. Externally, if all users have to code time limits and maximum memory for their programs, priorities are known before execution. Internally, a next processor burst time prediction such as that of SPF can be used to determine priorities dynamically.

A priority scheduling algorithm can leave some low-priority processes in the ready queue indefinitely. If the system is heavily loaded, it is a great probability that there is a higher- priority process to grab the processor. This is called the starvation problem. One solution for the starvation problem might be to gradually increase the priority of processes that stay in the system for a long time.

Example 2.

Following may be used as a priority defining function: Priority (n) = 10 + t (^) now – ts(n) – tr(n) – cpu(n) where ts(n) : the time process n is submitted to the system tr(n) : the time process n entered to the ready queue last time cpu(n) : next processor burst length of process n t (^) now : current time

QUESTIONS

1. Construct an example to compare the Shortest Job First strategy of processor scheduling with a Longest Job First strategy, in terms of processor utilization, turnaround time and throughput. 2. The following jobs are in the given order in the ready queue:

EE442 Operating Systems Ch. 2 Process Scheduling

Job CPU Burst(msec) Priority A 6 3 B 1 1 C 2 3 D 1 4 E 3 2

None of these jobs have any I/O requirement.

a. what is the turnaround time of each job with First come First Served, Shortest Job First, Round Robin (time quantum=1) and non-preemptive priority scheduling? Assume that the operating system has a context switching overhead of 1 msec. for saving and another 1 msec. for loading the registers of a process.

b. what is the waiting time for each job with each of the four scheduling techniques and assumption as in part a?

3. The following data is given for a computer system employing Round-Robin processor Scheduling with time slice=5, if two processes are to enter to the ready queue at the same time then they will enter in the alphabetical order of their names:

process arrival CPU I/0 CPU A 0 4 5 6 B 3 3 - - C 10 2 7 7

a. Assuming that context switch time is 0, draw the Gannt Chart for the above processes, and calculate the average waiting time and CPU utilization.

b. Assuming context switch time is 1, repeat part 'a',

c. Discuss briefly how the time slice should be selected to increase the system performance, given average CPU burst time, average I/O time, and the context switch time.

4. Consider the following job arrival and CPU burst times given:

Job Arrival time CPU burst A 0 7 B 2 4 C 3 1 D 6 6

a. Using the shortest job first scheduling method, draw the Gannt chart (showing the order of execution of these jobs), and calculate the average waiting time for this set of jobs.

b. Repeat a. using the shortest remaining time first scheduling method.

c. What is the main difference between these two methods?

5. Explain the following briefly:

a. What is an I/O bound job?

EE442 Operating Systems Ch. 2 Process Scheduling

CPU and I/0 Bursts

Arrival Process 1st CPU 1st I/O 2nd CPU 2nd I/O 3rd CPU 0 A 4 4 4 4 4 2 B 6 2 6 2 - 3 C 2 1 2 1 - 7 D 1 1 1 1 1

11. Show the execution of the following processes on Gannt Charts for the processor and the I/O device if Shortest Remaining Time First Algorithm for the Processor is used. Find also the average waiting time in ready queue. If the processess are to enter to the ready queue at the same time due to a. preemption of the processor, b. new submission, or c. completion of I/O operation, then the process of case a. , will be in front of the process of case b. , which will be in front of the process of case c.. Assume that I/O queue works in First Come First Served manner.

CPU and I/0 Bursts

Arrival Process 1st CPU 1st I/O 2nd CPU 2nd I/O 3rd CPU 0 A 4 4 4 4 4 2 B 8 1 8 1 - 3 C 1 1 1 1 -

12. Consider a priority based processor scheduling algorithm such that whenever there is a process in the ready queue having priority higher priority than the one executing in CPU, it will force the executing process to prempt the CPU, and itself will grab the CPU. If there are more then one such processes having highests priority, then among these the one that entered into the ready queue first should be chosen. Assume that all the processes have a single CPU burst and have no I/O operation and consider the following table:

Process id Submit (i) msec Burst(i) msec P1 0 8 P2 2 4 P3 3 2

where Submit(i) denotes when process Pi is submitted into the system (assume they are submitted just before the tic of the clock) and Burst(i) denotes the length of the CPU burst for process Pi. Let let Tnow to denote the present time and Execute(i) to denote the total execution of process Pi in cpu until Tnow. Assuming that the priorities are calculated every msec (just after the tic of the clock), draw the corresponding Gannt charts for the following priority formulas, which are valid when the process has been submitted but not terminated yet,

a. Priority(i)= Tnow-Submit(i)

b. Priority(i)= Burst(i)-Execute(i)

c. Priority(i)=(Burst(i)-Execute(i)) -

13. Consider the following job arrival and CPU, I/O burst times given. Assume that context switching time is negligible in the system and there is a single I/O device, which operates in first come first served manner,

EE442 Operating Systems Ch. 2 Process Scheduling

process arrival t. CPU-1 I/O-1 CPU- A 0 2 4 4 B 1 1 5 2 C 8 2 1 3

Draw the Gannt charts both for the CPU and the I/O device., and then find out what is the average turn around time and cpu utilization for

a. first come first served

b. round robin

processor scheduling algorihms.

14. Consider the following job arrival:

process arrival time next CPU burst A 0 7 B 1 5 C 2 3 D 5 1

a. Draw the Gannt chart for the CPU if nonpreemptive SPF scheduling is used b. Repeat part a. if preemptive SPF scheduling is used c. Repeat part a. if nonpreemptive priority based CPU scheduling is used with

priority (i)= 10 + tnow - tr(i) – cpu(i)

where ts(i)=the time process i is submitted to the sytem, tr(i)= the time proceess i entered to the ready queue last time, cpu(i)=next cpu burst length of process i, tnow=current time.

The process having the highest priority will grab the CPU. In the case more than one processes having the same priority, then the one being the first in the alphabetical order will be chosen.

d. For each of above cases indicate if starvation may occur or not

EE442 Operating Systems Ch. 3 Memory Management

Normally, a process swapped out will eventually be swapped back into the same partition. But this restriction can be relaxed with dynamic relocation.

In some cases, a process executing may request more memory than its partition size. Say we have a 6 KB process running in 6 KB partition and it now requires a more memory of 1 KB. Then, the following policies are possible:

  • Return control to the user program. Let the program decide either quit or modify its operation so that it can run (possibly slow) in less space.
  • Abort the process. (The user states the maximum amount of memory that the process will need, so it is the user’s responsibility to stick to that limit)
  • If dynamic relocation is being used, swap the process out to the next largest PQ and locate into that partition when its turn comes.

The main problem with the fixed partitioning method is how to determine the number of partitions, and how to determine their sizes.

If a whole partition is currently not being used, then it is called an external fragmentation. And if a partition is being used by a process requiring some memory smaller than the partition size, then it is called an internal fragmentation.

3.2 Variable Partitioning

With fixed partitions we have to deal with the problem of determining the number and sizes of partitions to minimize internal and external fragmentation. If we use variable partitioning instead, then partition sizes may vary dynamically.

In the variable partitioning method, we keep a table (linked list) indicating used/free areas in memory. Initially, the whole memory is free and it is considered as one large block. When a new process arrives, the OS searches for a block of free memory large enough for that process. We keep the rest available (free) for the future processes. If a block becomes free, then the OS tries to merge it with its neighbors if they are also free.

There are three algorithms for searching the list of free blocks for a specific amount of memory.

First Fit : Allocate the first free block that is large enough for the new process. This is a fast algorithm.

OS 2K P1 (2K) 6K Empty (6k)

12K P2 (9K) Empty (3K)

External fragmentation

Internal fragmentation

In this composition of memory, if a new process, P3, requiring 8 KB of memory comes, although there is enough total space in memory, it can not be loaded because fragmentation.

EE442 Operating Systems Ch. 3 Memory Management

Best Fit : Allocate the smallest block among those that are large enough for the new process. In this method, the OS has to search the entire list, or it can keep it sorted and stop when it hits an entry which has a size larger than the size of new process. This algorithm produces the smallest left over block. However, it requires more time for searching all the list or sorting it.

Worst Fit : Allocate the largest block among those that are large enough for the new process. Again a search of the entire list or sorting it is needed. This algorithm produces the largest over block.

Example 3. Consider the following memory map and assume a new process P4 comes with a memory requirement of 3 KB. Locate this process.

a. First fit algorithm allocates from the 10 KB block. b. Best fit algorithm allocates from the 4 KB block. c. Worst fit algorithm allocates from the 16 KB block.

New memory arrangements with respect to each algorithms will be as follows:

First Fit Best Fit Worst Fit

At this point, if a new process, P5 of 14K arrives, then it would wait if we used worst fit algorithm, whereas it would be located in cases of the others.

Compaction: Compaction is a method to overcome the external fragmentation problem. All free blocks are brought together as one large block of free space. Compaction requires dynamic relocation. Certainly, compaction has a cost and selection of an optimal compaction strategy is difficult. One method for compaction is swapping out those processes that are to be moved within the memory, and swapping them into different memory locations.

OS P 10 KB P 16 KB P 4 KB

OS P P 7 KB P 16 KB P 4 KB

OS P 10 KB P 16 KB P P 1 KB

OS P 10 KB P P 13 KB P 4 KB

OS P 20 KB P 7 KB P 10 KB

OS P P P 37 KB

Compaction