Add the rest of university notes
This commit is contained in:
366 files changed
+9844
-110
No files matched your search
@@ -26,7 +26,7 @@ The type of algorithm used by the scheduler is influenced by the type of operati
|
||||
- Invoked very frequency, hence must be fast
|
||||
- Usually called in response to *clock interrupts*, *I/O interrupts*, or *blocking system calls*
|
||||
|
||||

|
||||

|
||||
|
||||
**Non-preemptive** processes are only interrupted voluntarily (e.g. I/O operation or "nice" system call `yield()`)
|
||||
>Windows 3.1 and DOS were non-preemptive
|
||||
@@ -67,7 +67,7 @@ Concept: a non-preemptive algorithm that operates as a strict queuing mechanism
|
||||
| Positional fairness | Favours long processes over short ones (think supermarket checkout) || |
|
||||
| Easy to implement | Could compromise resource utilisation |
|
||||
|
||||

|
||||

|
||||
|
||||
**Shortest job first**
|
||||
A non-preemptive algorithm that starts processes in order of ascending processing time using a provided estimate of the processing
|
||||
@@ -78,7 +78,7 @@ A non-preemptive algorithm that starts processes in order of ascending processin
|
||||
| - | Fairness and predictability are compromised |
|
||||
| - | Processing times need to be known in advanced |
|
||||
|
||||

|
||||

|
||||
|
||||
**Round Robin**
|
||||
A preemptive version of FCFS that focuses context switches at periodic intervals or time slices
|
||||
@@ -100,7 +100,7 @@ The length of the time slice must be carefully considered.
|
||||
>A small time slice (~ 1ms) gives a good response time.
|
||||
>A large time slice (~ 1000ms) gives a high throughput.
|
||||
|
||||

|
||||

|
||||
|
||||
**Priority Queue**
|
||||
A preemptive algorithm that schedules processes by priority
|
||||
@@ -115,10 +115,10 @@ A preemptive algorithm that schedules processes by priority
|
||||
Low priority starvation only happens when a static priority level is used.
|
||||
You could give higher priority processes a larger time slice to improve efficiency
|
||||
|
||||

|
||||

|
||||
|
||||
Exam Q 2013: Which algorithms above lead to starvation?
|
||||
>Shortest job first and highest priority first.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
@@ -10,7 +10,7 @@ A process consists of two **fundamental** units
|
||||
|
||||
A process can share its resources between multiple execution traces, e.g multiple threads running in the same resource environment.
|
||||
|
||||

|
||||

|
||||
|
||||
Every thread has its own *execution context* (e.g. program counter, stack, registers).
|
||||
All threads have **access** to the process' **shared resources**
|
||||
@@ -22,7 +22,7 @@ All threads have **access** to the process' **shared resources**
|
||||
Similar to processes, threads have:
|
||||
**States**, **transitions** and a **thread control block**
|
||||
|
||||

|
||||

|
||||
|
||||
The *registers*, *stack* and *state* are all specific to the registers. When a context switch occurs they must be stored in the **thread control block**.
|
||||
|
||||
@@ -60,7 +60,7 @@ Such activities should be carried out in parallel on threads. e.g. web-servers,
|
||||
**Kernel** threads - ask the OS to create a tread for the user and give it to the user.
|
||||
**Hybrid** implementations - is what is used in windows 10
|
||||
|
||||

|
||||

|
||||
|
||||
**Pros and cons of user threads**
|
||||
|
||||
@@ -85,7 +85,7 @@ Advantages:
|
||||
|
||||
However frequent **mode switches** take place, resulting in a lower performance.
|
||||
|
||||

|
||||

|
||||
|
||||
Kernel threads are slower to create and sync that user level however user level cannot exploit parallelism.
|
||||
|
||||
@@ -96,7 +96,7 @@ Kernel threads are slower to create and sync that user level however user level
|
||||
>
|
||||
>User application sees user threads and creates/schedules these (an unrestricted number)
|
||||
|
||||

|
||||

|
||||
|
||||
Thread libraries provide an API for managing threads
|
||||
Thread libraries can be implemented
|
||||
@@ -113,9 +113,9 @@ Examples of thread APIs include **POSIX PThreads**, windows threads and Java thr
|
||||
`pthread_attr_init` - Thread Attributes (e.g. priority)
|
||||
`pthread_attr_destroy` - Release Attributes
|
||||
|
||||
$ ~ man `pthread_create` returns the help page
|
||||
`$ ~ man pthread_create` returns the help page
|
||||
|
||||

|
||||

|
||||
|
||||
```
|
||||
$ ~ HELLO from thread 10
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
Exam 2013: Explain how you would prevent starvation in a priority queue algorithm?
|
||||
|
||||

|
||||

|
||||
|
||||
The solution to this is to momentarily boost thread A's priority level, this will let A do what it what's to do and release resource X so that B and C can run.
|
||||
|
||||
@@ -38,9 +38,9 @@ Feedback queues are highly configurable and offer significant flexibility.
|
||||
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
If you give a couple of the threads the highest priority level, you can freeze your computer. (causes starvation for low priority threads)
|
||||
|
||||
@@ -81,7 +81,7 @@ Both ways *cannot* guarantee hard deadlines.
|
||||
|
||||
A **weighting scheme** is used to take difference priorities into account.
|
||||
|
||||
<img src="/lectures/osc/assets/k.png" alt="alt text" style="zoom:60%;" />
|
||||
<img src="assets/k.png" alt="alt text" style="zoom:60%;" />
|
||||
|
||||
The tasks with the **lowest proportional amount** of "used CPU time" are selected first. (Shorter tasks picked first if Wi is the same).
|
||||
|
||||
@@ -115,9 +115,9 @@ Windows will allocate the **highest priority threads** to the individual CPUs/co
|
||||
>
|
||||
> **Unrelated** processes threads that are **independent**, possibly started by **different users** running different programs.
|
||||
|
||||

|
||||

|
||||
|
||||
Threads belong to the same process are are cooperating e.g. they **exchange messages** or **share information**
|
||||
Threads belong to the same process are cooperating e.g. they **exchange messages** or **share information**
|
||||
|
||||
The aim is to get threads running as much as possible, at the **same time across multiple CPU**s.
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ Counter++ consists of three separate actions.
|
||||
|
||||
The above actions are **not** "atomic". This means they can be interrupted by the timer.
|
||||
|
||||

|
||||

|
||||
|
||||
TCB - *Thread Control Block*
|
||||
|
||||
@@ -63,9 +63,9 @@ void print() {
|
||||
|
||||
If the two threads are **interleaved** one after the other, there is no issue.
|
||||
|
||||

|
||||

|
||||
|
||||
However if **interleaved** like this they do interact. The global variable used to store the character in thread 1, is overwritten when thread 2 runs. This means 1+1+1 = 2
|
||||
However, if **interleaved** like this they do interact. The global variable used to store the character in thread 1, is overwritten when thread 2 runs. This means 1+1+1 = 2
|
||||
|
||||
## Bounded Buffer
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ The process/thread that acquires the lock must **release the lock** - in contras
|
||||
| Context switches can be **avoided**. | Calls to `acquire()` result in **busy waiting**. Shocking performance on single CPU systems. |
|
||||
| Efficient on multi-core systems when locks are **held for a short time**. | A thread can waste it's entire time slice busy waiting. |
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ Semaphores within the **same process** can be declared as **global variables** o
|
||||
> * `sem_wait()` - decrements the value of the semaphore.
|
||||
> * `sem_post()` - increments the values of the semaphore.
|
||||
|
||||

|
||||

|
||||
|
||||
Synchronising code does result in a **performance penalty**
|
||||
|
||||
@@ -198,7 +198,7 @@ The simplest version of this problem has **one producer**, **one consumer** and
|
||||
* `sync` **synchronises** access to the **buffer** (counter) which is initialised to 1.
|
||||
* `delay_consumer` ensures that the **consumer** goes to **sleep** when there are no items available, initialised to 0.
|
||||
|
||||

|
||||

|
||||
|
||||
It is obvious that any manipulations of count will have to be **synchronised**.
|
||||
|
||||
@@ -231,4 +231,4 @@ A different variant of the problem has `n` consumers and `m` producers and a fix
|
||||
|
||||
The `empty` and `full` are **counting semaphores** and represent **resources**.
|
||||
|
||||

|
||||

|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## The Dining Philosophers Problem
|
||||
|
||||
<img src="/lectures/osc/assets/w.png" alt="img" style="zoom:67%;" />
|
||||
<img src="assets/w.png" alt="img" style="zoom:67%;" />
|
||||
|
||||
The problem is defined as:
|
||||
|
||||
@@ -50,7 +50,7 @@ The solution uses:
|
||||
> * `sync` : one **semaphore/mutex** to enforce **mutual exclusion** of the critical section (while updating the **states** of `hungry` `thinking` and `eating`)
|
||||
> * A philosopher can only **start eating** if their neighbours are **not eating**.
|
||||
|
||||

|
||||

|
||||
|
||||
#### Code for Solution 3
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ A correct implementation requires:
|
||||
>
|
||||
> `rwSync` : a semaphore that synchronises the readers and writers, set by the first/last reader.
|
||||
|
||||

|
||||

|
||||
|
||||
`sync` is used to `mutex_lock` and `mutex_unlock` when the `iReadCount` is being modified.
|
||||
|
||||
@@ -70,7 +70,7 @@ Unless `iReadCount` reaches 0, writing will not happen. **This means writers can
|
||||
> * `sReadTry`: to **stop readers** when there is a **writer waiting**.
|
||||
> * `sResource`: to **synchronise** the resource for **reading/writing**.
|
||||
|
||||

|
||||

|
||||
|
||||
[explanation time stamp 43:35]
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ The operating system provides **memory abstraction** for the user. Otherwise mem
|
||||
|
||||
#### Partitioning
|
||||
|
||||

|
||||

|
||||
|
||||
##### Contiguous memory management
|
||||
|
||||
@@ -52,7 +52,7 @@ Where memory is allocated in multiple blocks, or segments, which may not be plac
|
||||
>
|
||||
> * Overlays enable the **programmer** to use **more memory than available**.
|
||||
|
||||

|
||||

|
||||
|
||||
##### Short comings of mono-programming
|
||||
|
||||
@@ -77,7 +77,7 @@ Why Multi-Programming is better theoretically
|
||||
> * The probability that **all** *n* **processes are waitying for I/O is *p*^n^
|
||||
> * Therefore CPU utilisation is given by $1 - p^{n}$
|
||||
|
||||

|
||||

|
||||
|
||||
With an **I/O wait time of 20%** almost **100% CPU utilisation** can be achieved with four processes ($1-0.2^{4}$)
|
||||
|
||||
@@ -85,7 +85,7 @@ With an **I/O wait time of 90%**, 10 processes can achieve about **65% CPU utili
|
||||
|
||||
CPU utilisation **goes up** with the **number of processes** and **down** for **increasing levels of I/O**.
|
||||
|
||||

|
||||

|
||||
|
||||
**Assume that**:
|
||||
|
||||
@@ -124,7 +124,7 @@ CPU utilisation **goes up** with the **number of processes** and **down** for **
|
||||
* Reduces **internal fragmentation**
|
||||
* The **allocation** of processes to partitions must be **carefully considered**.
|
||||
|
||||

|
||||

|
||||
|
||||
**One private queue per partition**:
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ When a program is run, it does not know in advance which partition it will occup
|
||||
|
||||
**Protection**: Once you can have two programs in memory at the same time, protection must be enforced.
|
||||
|
||||

|
||||

|
||||
|
||||
**Logical Address**: is a memory address seen by the process
|
||||
|
||||
@@ -76,7 +76,7 @@ Two special purpose registers are maintained in the CPU (the **MMU**) containing
|
||||
>
|
||||
> NOTE: This requires **hardware support** (which didn't exist in the early days).
|
||||
|
||||
<img src="/lectures/osc/assets/G.png" alt="registers" style="zoom:80%;" />
|
||||
<img src="assets/G.png" alt="registers" style="zoom:80%;" />
|
||||
|
||||
#### Dynamic Partitioning
|
||||
|
||||
@@ -91,7 +91,7 @@ Two special purpose registers are maintained in the CPU (the **MMU**) containing
|
||||
> * A **variable number of partitions** of which the **size** and **starting address** can **change over time**.
|
||||
> * A process is allocated the **exact amount** of **contiguous memory it requires**, thereby preventing internal fragmentation.
|
||||
|
||||

|
||||

|
||||
|
||||
**Swapping** holds some of the **processes** on the drive and **shuttles processes** between the drive and main memory as necessary
|
||||
|
||||
@@ -147,6 +147,6 @@ A more **sophisticated data structure** is required to deal with a **variable nu
|
||||
> * Each link **contains data items** e.g. **start of memory block**, **size** and a flag for free and allocated
|
||||
> * It also contains a pointer to the next link.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
@@ -73,11 +73,11 @@ Paging uses the principles of **fixed partitioning** and **code re-location** to
|
||||
> * **Internal fragmentation** is reduced to the **last block only** (e.g. previous example the third block, only 3 Kb will be used)
|
||||
> * There is **no external fragmentation**, since physical blocks are **stacked directly onto each other** in main memory.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
A **page** is a **small block** of **contiguous memory** in the **logical address space** (as seen by the process)
|
||||
|
||||
@@ -93,9 +93,10 @@ A **page** is a **small block** of **contiguous memory** in the **logical addres
|
||||
* i.e a **set of base registers** has to be maintained for each process
|
||||
* The base registers are stored in the **page table**
|
||||
|
||||

|
||||

|
||||
|
||||
The page table can be seen as a **function**, that **maps the page number** of the logical address **onto the frame number** of the physical address
|
||||
|
||||
$$
|
||||
frameNumber = f(pageNumber)
|
||||
$$
|
||||
@@ -103,7 +104,7 @@ $$
|
||||
* The **page number** is used as an **index to the page table** that lists the **location of the associated frame**.
|
||||
* It is the OS' duty to maintain a list of **free frames**.
|
||||
|
||||

|
||||

|
||||
|
||||
We can see that the **only difference** between the logical address and physical address is the **4 left most bits** (the **page number and frame number**). As **pages and frames are the same size**, then the **offset value will be the same for both**.
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ Benefits of paging
|
||||
* The **left most** $n$ **bits** that represent the **page number** (and frame number they're the same thing)
|
||||
* $n$ is often 4 bits
|
||||
|
||||

|
||||

|
||||
|
||||
#### Steps in Address Translation
|
||||
|
||||
@@ -44,7 +44,7 @@ Benefits of paging
|
||||
|
||||
### Principle of Locality
|
||||
|
||||

|
||||

|
||||
|
||||
We have more pages here, than we can physically store as frames.
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* The principle behind TLBs is similar to other types of **caching in operating systems**. They normally store anywhere from 16 to 512 pages.
|
||||
* Remember: **locality** states that processes make a large number of references to a small number of pages.
|
||||
|
||||

|
||||

|
||||
|
||||
The split arrows going into the TLB represent searching in parallel.
|
||||
|
||||
@@ -42,15 +42,19 @@ The split arrows going into the TLB represent searching in parallel.
|
||||
> * Performance evaluation of TLBs
|
||||
>
|
||||
> * For an 80% hit rate, the estimated access time is:
|
||||
>
|
||||
> $$
|
||||
> 120\cdot 0.8 + 220\cdot (1-0.8)=140ns
|
||||
> $$
|
||||
>
|
||||
> (**40% slowdown** relative to absolute addressing)
|
||||
>
|
||||
> * For a 98% hit rate, the estimated access time is:
|
||||
>
|
||||
> $$
|
||||
> 120\cdot 0.98 + 220\cdot (1-0.98)=122ns
|
||||
> $$
|
||||
>
|
||||
> (**22% slowdown**)
|
||||
>
|
||||
> NOTE: **page tables** can be **held in virtual memory** => **further slow down** due to **page faults**.
|
||||
@@ -68,8 +72,6 @@ A **normal page table size** is proportional to the number of pages in the virtu
|
||||
>* *Solution*: Use a **hash function** that transforms page numbers (*n* bits) into frame numbers (*m* bits) - Remember *n* > *m*
|
||||
> * The has functions turns a page number into a potential frame number.
|
||||
|
||||

|
||||
|
||||
So when looking for the page's frame location. We have to sequentially search through the table until we hit a match, we then get the frame number from the index - in this case 4.
|
||||
|
||||
#### Inverted Page Table Entry
|
||||
@@ -80,9 +82,9 @@ So when looking for the page's frame location. We have to sequentially search th
|
||||
> * **Protection** bits (Read/Write/Execute)
|
||||
> * **Chaining Pointer** - This field points towards the next frame that has exactly the same VPN. We need this to solve collisions
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
Due to the hash function, we now only have to look through all entries with **VPN**: 1 instead of all the entries.
|
||||
|
||||
@@ -130,6 +132,7 @@ Due to the hash function, we now only have to look through all entries with **VP
|
||||
NOTE: This doesn't take into account TLBs.
|
||||
|
||||
The expected access time is **proportional to page fault rate** when keeping page faults into account.
|
||||
|
||||
$$
|
||||
T_{a} \space\space\alpha \space\space p
|
||||
$$
|
||||
@@ -160,9 +163,8 @@ $$
|
||||
>
|
||||
> This is a pretty bad algorithm <s>unsurprisingly</s>
|
||||
|
||||

|
||||

|
||||
|
||||
Explanation at 53:40
|
||||
|
||||
Shaded squares on the top row are page faults. Shaded squares in the grid are when a new page is brought into memory.
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
> * It is faster, but can still be **slow if the list is long**.
|
||||
> * The **time spent** on **maintaining** the list is **reduced**.
|
||||
|
||||

|
||||

|
||||
|
||||
##### Not Recently Used (NRU)
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
>
|
||||
> This algorithm can be **implemented in hardware** using a **counter** that is incremented after each instruction ...
|
||||
|
||||

|
||||

|
||||
|
||||
This will look familiar to the FIFO algorithm however, when a page is used, that is like its just come in.
|
||||
|
||||
@@ -88,7 +88,7 @@ The **working set** is a subset of the resident set that is actually needed for
|
||||
* The set of pages used within a pre-specified time interval
|
||||
* The **working set size** can be used as a guide for the number of frames that should be allocated to a process.
|
||||
|
||||

|
||||

|
||||
|
||||
The working set is a **function of time** $t$:
|
||||
|
||||
@@ -96,9 +96,11 @@ The working set is a **function of time** $t$:
|
||||
* **Stable** intervals alternate with intervals of **rapid change**
|
||||
|
||||
$|W(t,k)|$ is then a variable in time. Specifically:
|
||||
|
||||
$$
|
||||
1\le |W(t,k)| \le min(k, N)
|
||||
$$
|
||||
|
||||
where $N$ is the total number of pages of the process. All the maths is saying is that the size of the working set can be as small as **one** or as large as **all the pages in the process**.
|
||||
|
||||
Choosing the right value for $k$ is important:
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
>
|
||||
> Hard disks are currently about 4 orders of magnitude slower than main memory.
|
||||
|
||||

|
||||

|
||||
|
||||
#### Low Level Format
|
||||
|
||||
@@ -46,18 +46,20 @@ NOTE: disk capacity is reduced due to preamble & ECC
|
||||
|
||||
* **Transfer time**: time to transfer the data
|
||||
|
||||

|
||||

|
||||
|
||||
Multiple requests may be happening at the same time (concurrently), so access time may be increased by **queuing time**
|
||||
|
||||
In this scenario, dominance of seek time leaves room for **optimisation** by carefully considering the order of read operations.
|
||||
|
||||

|
||||

|
||||
|
||||
The **estimated seek time** (i.e to move the arm from one track to another) is approximated by:
|
||||
|
||||
$$
|
||||
T_{s} = n \times m + s
|
||||
$$
|
||||
|
||||
In which $T_{s}$ denotes the estimated seek time, $n$ the **number of tracks** to be crossed, $m$ the **crossing time per track** and $s$ any **additional startup delay**.
|
||||
|
||||
> Let us assume a disk that rotates at 3600 rpm
|
||||
@@ -66,9 +68,11 @@ In which $T_{s}$ denotes the estimated seek time, $n$ the **number of tracks** t
|
||||
> * The average **rotational latency** $T_{r}$ is then 8.3 ms
|
||||
>
|
||||
> Let **b** denote the **number of bytes transferred**, **N** the **number of bytes per track**, and **rpm** the **rotation speed in rotations per minute**, the per track, the transfer time, $T_{t}$, is then given by:
|
||||
>
|
||||
> $$
|
||||
> T_{t} = \frac b N \times \frac {ms\space per\space minute}{rpm}
|
||||
> $$
|
||||
>
|
||||
> $N$ bytes take 1 revolution => $\frac{60000}{3600}$ ms = $\frac {ms\space per\space minute}{rpm}$
|
||||
>
|
||||
> $b$ contiguous bytes takes $\frac{b}{N}$ revolutions.
|
||||
@@ -119,7 +123,7 @@ In a dynamic situation, several I/O requests will be **made over time** that are
|
||||
>
|
||||
> The total length is: `|11-1|+|1-36|+|36-16|+|16-34|+|34-9|+|9-12|=111`
|
||||
>
|
||||
> 
|
||||
> 
|
||||
|
||||
|
||||
|
||||
@@ -131,7 +135,7 @@ In a dynamic situation, several I/O requests will be **made over time** that are
|
||||
>
|
||||
> Total length is: `|11-12|+|12-9|+|9-16|+|16-1|+|1-34|+|34-36|=61`
|
||||
>
|
||||
> 
|
||||
> 
|
||||
>
|
||||
> Disadvantages:
|
||||
>
|
||||
@@ -148,7 +152,7 @@ In a dynamic situation, several I/O requests will be **made over time** that are
|
||||
>
|
||||
> Total length: `|11-12|+|12-16|+|16-34|+|34-36|+|36-9|+|9-1|=60`
|
||||
>
|
||||
> 
|
||||
> 
|
||||
>
|
||||
> **Disadvantages**:
|
||||
>
|
||||
|
||||
@@ -79,7 +79,7 @@ Retrieving a file comes down to **searching the directory file** as fast as poss
|
||||
* Indexes or **hash tables** can be used.
|
||||
* They can store all **file related attributes** (file name, disk address - Windows) or they can **contain a pointer** to the data structure that contains the details of the file (Unix)
|
||||
|
||||

|
||||

|
||||
|
||||
##### System Calls
|
||||
|
||||
@@ -140,9 +140,9 @@ Disks are usually divided into **multiple partitions**
|
||||
> * **Root directory**: the top of the file-system tree
|
||||
> * **Data**: files and directories
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
Free space management with linked list (on the left) and bitmaps (on the right)
|
||||
|
||||
@@ -163,9 +163,9 @@ Apart from the free space memory tables, there is a number of key data structure
|
||||
* A **system-wide open file table**, containing a copy of the FCB for every currently open file in the system, including location on disk, file size and **open count** (number of processes that use the file)
|
||||
* A **per-process open file table**, containing a pointer to the system open file table.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
@@ -56,17 +56,17 @@ To avoid external fragmentation, files are stored in **separate blocks** that ar
|
||||
> * **Random access is very slow**, to retrieve a block in the middle, one has to walk through the list from the start
|
||||
> * There is some **internal fragmentation** - on average the last half of the block is left unused
|
||||
> * Internal fragmentation will reduce for **smaller block sizes**
|
||||
> * However **larger blocks** will be **faster**
|
||||
> * However, **larger blocks** will be **faster**
|
||||
> * Space for data is lost within the blocks due to the pointer, the data in a **block is no longer a power of 2**
|
||||
> * **Diminished reliability**: if one block is corrupted/lost, access to the rest of the file is lost.
|
||||
|
||||

|
||||

|
||||
|
||||
##### File Allocation Tables
|
||||
|
||||
* Store the linked-list pointers in a **separate index table** called a **file allocation table** in memory.
|
||||
|
||||

|
||||

|
||||
|
||||
> **Advantages**
|
||||
>
|
||||
@@ -88,4 +88,4 @@ Each file has a small data structure (on disk) called an **I-node** (index-node)
|
||||
|
||||
I-nodes are composed of **direct block pointers** (usually 10) **indirect block pointers** or a combination thereof.
|
||||
|
||||

|
||||

|
||||
Reference in new issue
Block a user