Add the rest of university notes

This commit is contained in:
John Gatward committed 2026-10-04 14:02:35 +01:00
1 parent c1b84c7f7d
commit d0f27f276b
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*
![Image](/lectures/osc/assets/1.png)
![Image](assets/1.png)
**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 |
![Image](/lectures/osc/assets/2.png)
![Image](assets/2.png)
**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 |
![Image](/lectures/osc/assets/3.png)
![Image](assets/3.png)
**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.
![Image](/lectures/osc/assets/4.png)
![Image](assets/4.png)
**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
![Image](/lectures/osc/assets/5.png)
![Image](assets/5.png)
Exam Q 2013: Which algorithms above lead to starvation?
>Shortest job first and highest priority first.
![Image](/lectures/osc/assets/6.png)
![Image](/lectures/osc/assets/7.png)
![Image](assets/6.png)
![Image](assets/7.png)
+7 -7
View File
@@ -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.
![Image](/lectures/osc/assets/9.png)
![Image](assets/9.png)
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**
![Image](/lectures/osc/assets/a.png)
![Image](assets/A.png)
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
![Image](/lectures/osc/assets/d.png)
![Image](assets/d.png)
**Pros and cons of user threads**
@@ -85,7 +85,7 @@ Advantages:
However frequent **mode switches** take place, resulting in a lower performance.
![Image](/lectures/osc/assets/e.png)
![Image](assets/E.png)
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)
![Image](/lectures/osc/assets/f.png)
![Image](assets/f.png)
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
![img](/lectures/osc/assets/g.png)
![img](assets/G.png)
```
$ ~ HELLO from thread 10
+6 -6
View File
@@ -10,7 +10,7 @@
Exam 2013: Explain how you would prevent starvation in a priority queue algorithm?
![alt text](/lectures/osc/assets/h.png)
![alt text](assets/h.png)
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.
![alt text](/lectures/osc/assets/i.png)
![alt text](assets/I.png)
![alt text](/lectures/osc/assets/j.png)
![alt text](assets/j.png)
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.
![alt text](/lectures/osc/assets/l.png)
![alt text](assets/L.png)
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.
+3 -3
View File
@@ -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.
![image](/lectures/osc/assets/p.png)
![image](assets/p.png)
TCB - *Thread Control Block*
@@ -63,9 +63,9 @@ void print() {
If the two threads are **interleaved** one after the other, there is no issue.
![img](/lectures/osc/assets/q.png)
![img](assets/Q.png)
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
+4 -4
View File
@@ -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. |
![img](/lectures/osc/assets/S.png)
![img](assets/S.png)
@@ -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.
![img](/lectures/osc/assets/t.png)
![img](assets/t.png)
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.
![img](/lectures/osc/assets/U.png)
![img](assets/U.png)
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**.
![img](/lectures/osc/assets/V.png)
![img](assets/V.png)
+2 -2
View File
@@ -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**.
![img](/lectures/osc/assets/x.png)
![img](assets/X.png)
#### Code for Solution 3
+2 -2
View File
@@ -49,7 +49,7 @@ A correct implementation requires:
>
> `rwSync` : a semaphore that synchronises the readers and writers, set by the first/last reader.
![img](/lectures/osc/assets/y.png)
![img](assets/Y.png)
`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**.
![img](/lectures/osc/assets/z.png)
![img](assets/Z.png)
[explanation time stamp 43:35]
+5 -5
View File
@@ -22,7 +22,7 @@ The operating system provides **memory abstraction** for the user. Otherwise mem
#### Partitioning
![img](/lectures/osc/assets/A.png)
![img](assets/A.png)
##### 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**.
![img](/lectures/osc/assets/B.png)
![img](assets/B.png)
##### 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}$
![cpu_util_form](/lectures/osc/assets/C.png)
![cpu_util_form](assets/C.png)
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**.
![cpu_util_graph](/lectures/osc/assets/D.png)
![cpu_util_graph](assets/d.png)
**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**.
![process_alloc](/lectures/osc/assets/E.png)
![process_alloc](assets/E.png)
**One private queue per partition**:
+5 -5
View File
@@ -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.
![relative_mmu](/lectures/osc/assets/F.png)
![relative_mmu](assets/f.png)
**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.
![dynamic_partitioning](/lectures/osc/assets/H.png)
![dynamic_partitioning](assets/h.png)
**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.
![Memory Management with linked lists](/lectures/osc/assets/J.png)
![Memory Management with linked lists](assets/j.png)
![Linked lists for finding free memory](/lectures/osc/assets/K.png)
![Linked lists for finding free memory](assets/k.png)
+6 -5
View File
@@ -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.
![Paging in main memory](/lectures/osc/assets/L.png)
![Paging in main memory](assets/L.png)
![Paging processor's view](/lectures/osc/assets/M.png)
![Paging processor's view](assets/M.png)
![Paging](/lectures/osc/assets/P.png)
![Paging](assets/p.png)
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**
![Mapping page tables](/lectures/osc/assets/Q.png)
![Mapping page tables](assets/Q.png)
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**.
![address translation](/lectures/osc/assets/R.png)
![address translation](assets/r.png)
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**.
+2 -2
View File
@@ -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
![address composition](/lectures/osc/assets/S.png)
![address composition](assets/S.png)
#### Steps in Address Translation
@@ -44,7 +44,7 @@ Benefits of paging
### Principle of Locality
![virtual memory](/lectures/osc/assets/T.png)
![virtual memory](assets/t.png)
We have more pages here, than we can physically store as frames.
+9 -7
View File
@@ -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.
![TLB diagram](/lectures/osc/assets/W.png)
![TLB diagram](assets/w.png)
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.
![inverted page table](/lectures/osc/assets/x.webp)
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
![Inverted Page table entry](/lectures/osc/assets/Y.png)
![Inverted Page table entry](assets/Y.png)
![inverted page table address translation](/lectures/osc/assets/Z.png)
![inverted page table address translation](assets/Z.png)
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>
![FIFO page replacement](/lectures/osc/assets/a1.png)
![FIFO page replacement](assets/a1.png)
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.
+5 -3
View File
@@ -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**.
![clock replacement](/lectures/osc/assets/a2.png)
![clock replacement](assets/a2.png)
##### Not Recently Used (NRU)
@@ -54,7 +54,7 @@
>
> This algorithm can be **implemented in hardware** using a **counter** that is incremented after each instruction ...
![least used recently visualisation](/lectures/osc/assets/a3.png)
![least used recently visualisation](assets/a3.png)
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.
![working set](/lectures/osc/assets/a4.png)
![working set](assets/a4.png)
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:
+10 -6
View File
@@ -16,7 +16,7 @@
>
> Hard disks are currently about 4 orders of magnitude slower than main memory.
![hard drive diagram](/lectures/osc/assets/a5.png)
![hard drive diagram](assets/a5.png)
#### Low Level Format
@@ -46,18 +46,20 @@ NOTE: disk capacity is reduced due to preamble & ECC
* **Transfer time**: time to transfer the data
![hard drive access times](/lectures/osc/assets/a6.png)
![hard drive access times](assets/a6.png)
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.
![hard disk delay](/lectures/osc/assets/a7.png)
![hard disk delay](assets/a7.png)
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`
>
> ![FCFS](/lectures/osc/assets/a8.png)
> ![FCFS](assets/a8.png)
@@ -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`
>
> ![SSTF](/lectures/osc/assets/a9.png)
> ![SSTF](assets/a9.png)
>
> 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`
>
> ![scan algorithm](/lectures/osc/assets/b1.png)
> ![scan algorithm](assets/b1.png)
>
> **Disadvantages**:
>
+5 -5
View File
@@ -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)
![directory files](/lectures/osc/assets/b2.png)
![directory files](assets/b2.png)
##### 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
![unix partition composition](/lectures/osc/assets/b4.png)
![unix partition composition](assets/b4.png)
![Free block management](/lectures/osc/assets/b5.png)
![Free block management](assets/b5.png)
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.
![file tables](/lectures/osc/assets/b6.png)
![file tables](assets/b6.png)
![opening & reading a file](/lectures/osc/assets/b7.png)
![opening & reading a file](assets/b7.png)
+4 -4
View File
@@ -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.
![Linked list file storage](/lectures/osc/assets/b8.png)
![Linked list file storage](assets/b8.png)
##### File Allocation Tables
* Store the linked-list pointers in a **separate index table** called a **file allocation table** in memory.
![FAT](/lectures/osc/assets/b9.png)
![FAT](assets/b9.png)
> **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.
![I-nodes](/lectures/osc/assets/c1.png)
![I-nodes](assets/c1.png)