CSS 430 Operating Systems - Lecture Notes

What is the point of operating systems?

Definitions

Term Definition
Resource Allocator manages and allocates resources
Control Program controls the execution of user programs and operations of I/O devices
Kernel The one program running at all times

Lecture 1 2023-01-03

OS To Manage Hardware

Note

Pasted image 20230103153826.png

Difference Between Java and C++

Operating Systems History

Batch Systems - 50's

A job is assembled of the program data and control cards
Programmers pass their jobs to an operator and the operator batched jobs together
The OS transfers control from one job to another, and each job output is sent back to the programmer

Interaction from User to OS

Pasted image 20221230194157.png

The Operating system cannot access the mode bit as it determines system mode.

User Mode: execution done on behalf of the user
Monitor Mode- execution done on behalf of the operating system

Synchronous I/O

Async I/O and Interrupts

Multiprogramming

Timer Interrupt

Time Sharing Systems

Advanced Hardware


Pasted image 20230103172147.png

Lecture 2 2023-01-05

System Calls

When a user program executes a special instruction like trap

Note

With C++ the compiler will insert the trap into your assembly code, however with Assembly, you need to call it manually
G

Command Interpreters

The program that reads and interprets control statements

Shell

Pasted image 20230105153701.png

Now we more often use sshd instead of telnetd

Process

ps lists processes running (process status)

Tip

PID is process ID

A process includes:

Process Creation

Parent process creates children processes

Resource sharing

Process termination

Process termination occurs when

Upon process termination

Parent may terminate execution of children processes (via kill)) when

Producer-Consumer Problems

Pasted image 20230105154512.png
Producer Process

Direct Communication Example: Pipe

Pasted image 20230105154620.png

if (pipe<0){
//error
}
else

We will use dup2 to change the standard output and standard input

Discussion 1

Discussion 2

Discussion 3

Lecture 3 2023-01-010

Monolithic vs Micro Kernels

Pasted image 20230109144457.png

Virtualization

Pasted image 20230109144514.png

1980's intel implemented CVS ## Process Layout ![Pasted image 20230109144740.png](/img/user/Reference/Attachments/Pasted%20image%2020230109144740.png)

Process Tree

Pasted image 20230110154411.png

Process Control Block

Pasted image 20230108125815.png

Process State

Pasted image 20230108125328.png

Process Scheduling Queues

Pasted image 20230109145636.png

Inter-Process Communication

Communication Models

Pasted image 20230108134740.png

Shared Memory

import java.util.*;
public class BoundedBuffer
{
   public BoundedBuffer( ) {
      count = 0;
      in = 0;
      out = 0;
      buffer = new Object[BUFFER_SIZE];
   }
   public void enter( Object item ) { }
   public Object remove( ) { }
   public static final int BUFFER_SIZE = 5;
   private int count; // #items in buffer
   private int in; // points to the next free position
   private int out; // points to the next full position
   private Object[] buffer; // a reference to buffer

}

group 8

Question

In Unix, the first process is called init. All the others are descendants of “init”. The init process spawns a telnetd process that detects a new telnet connection. Upon a new connection, telnetd spawns a login process that then overloads a shell on it when a user successfully log in the system. Now, assume that the user types who | grep mfukuda | wc –l. Draw a process tree from init to those three commands. Add fork, exec, wait, and pipe system calls between any two processes affecting each other. If it’s tedious to draw an illustration directly here, draw an illustration on scratch paper, photograph it, and paste it to this google doc.

#430midterm

Question

Mickey Mouse is an undergraduate research assistant. He received the following instruction from his advisor:
Login uw1-320-20 with our project account “project”.
Go to the “~/src” directory.
Compile all.cpp files into a.out.
Check if the “project” account is running a.out in background. If so, make sure to terminate it.
Run a.out with its priority 5 and save its standard output into the “result.txt” file.
Archive all files under the “~/src” directory into “~/src.tar”.
Mickey was using “uw1-320-21” with his “mickey” account before he followed this instruction. When he tried to run “a.out”, he found that the “project” account was running a.out in background and its PID was 1234.

ssh project@uw1-320-20.edu
cd ~/src
g++ *.cpp 
ps 
kill -9 1234
nice -5 ./a.out > result.txt
tar -cvf - src > src.tar

Question

In Unix, the first process is called init. All the others are descendants !of “init”. The init process spawns a telnetd process that detects a new telnet connection. Upon a new connection, telnetd spawns a login process that then overloads a shell on it when a user successfully logs in the system. Now, assume that the user has typed a.out | grep hello, where a.out is an executable file compiled from the following C++ program. Draw a process tree from init to those two programs, (i.e. a.out and grep). (Note that your tree may have more three processes.) Add fork, exec, wait, and pipe system calls between any two processes affecting each other. For each pipe, indicate its direction with an arrow, (i.e., →).
Pasted image 20230110164543.png#panapto
!Pasted image 20230112201345.png

Lecture 4 2023-01-12

Carry over from last lecture

When no other processes are running, init process (process 0) goes into HLT (halt)

Shared memory (why you may not want to use) - number of computing loads (beyond say, 20) - synchronization

With shared memory, make sure there is inter process syncronization

Message Passing

Direct Communication

Socket

Socket is good for multiple computers
All I/O including IPC is handled with file descriptors (fd)

Indirect Communication

Thread Concepts

Process oriented computing
Pasted image 20230112124253.png
Multithreaded computing
Pasted image 20230112124311.png

	main()
tid1 = pthread_create(func, args...){


}
tid2 = pthread_create(func, args...){

}



function(){

}

Single vs multithreaded Processes

Java Threads


Thread class extension

class  Worker1 extends Thread {
	public void run() {
		while ( true )
			System.out.println(“I am a Worker Thread”);
	}
}

public class First {
	public static void main(String args[]) {
		First main = new First( );
	}
	First( ) {
		Worker1 runner = new Worker1();
		runner.start();
		while ( true )
			System.out.println(“I am the main thread”);
	}
}

Runnable Interface Implementation

// This Runnable interface has been defined by system
public interface Runnable {
	public abstract void run();
}

// You have to actually implement the run method.
class  Worker2 implements Runnable extends myBaseClass {
	public void run() {
		while ( true )
			System.out.println(“I am a Worker Thread”);
	}
}

public class Second {
	public static void main(String args[]) {
		Second main = new Second( )
	}
	Second( ) {
		Runnable runner = new Worker2();
		Thread thrd = new Thread(runner);
		thrd.start();
		while ( true )
			System.out.println(“I am the main thread”);
	}
}

CSS430-Unique ThreadOS

Pasted image 20230112124706.png

"java boot"

new thread is launched, thread id, parent id etc

Shell

ThreadOS Sys Lib

  1. SysLib.exec( String args[] ) loads the class specified in args[0], instantiates its object, simply passes the following elements of String array, (i.e., args[1], args[2], ...), and starts it as a child thread. It returns a child thread ID on success, otherwise -1.
  2. SysLib.join( ) waits for the termination of one of child threads. It returns the ID of the child thread that has woken up the calling thread. If it fails, it returns -1.
  3. SysLib.sleep( long millis ) sleeps the calling thread for given milliseconds.
  4. SysLib.exit( ) terminates the calling thread and wakes up its parent thread if this parent is waiting on join( ).
  5. SysLib.cin( StringBuffer s ) reads keyboard input to the StringBuffer s.
  6. SysLib.cout( String s )prints out the String s to the standard output. Like C's printf, it recognizes '\n' as a new-line character.
  7. SysLib.cerr( String s ) prints out the String s to the standard error. Like C's printf, it recognizes '\n' as a new-line character.
  8. SysLib.rawread( int blkNumber, byte[] b ) reads one block data to the byte array b from the block specified by blkNumber.
  9. SysLib.rawwrite( int blkNumber, byte[] b ) writes one block data from the byte array b to the block specified by blkNumber.
  10. SysLib.sync( ) writes back all on-memory data into a disk.

Prog 1BThreadOS Shell

import java.io.*;
import java.util.*;

class Shell extends Thread {
    public Shell( ) {
    }

    public void run( ) {
        for ( int line = 1; ; line++ ) {
            String cmdLine = "";
            do {
                StringBuffer inputBuf = new StringBuffer( );
                SysLib.cerr( "shell[" + line + "]% " );
                SysLib.cin( inputBuf );
                cmdLine = inputBuf.toString( );
            } while ( cmdLine.length( ) == 0 );
            String[] args = SysLib.stringToArgs( cmdLine );
            int first = 0;
            for ( int i = 0; i < args.length; i++ ) {
                if ( args[i].equals( ";" ) || args[i].equals( "&" )
                     || i == args.length - 1 ) {
                    String[] command = generateCmd( args, first, ( i==args.length - 1 ) ? i+1 : i );
                    if ( command != null ) {
                        // check if command[0] is “exit”. If so, get terminated
                        // otherwise, pass command to SysLib.exec( ).
                        // if aergs[i] is “&” don’t call SysLib.join( ). Otherwise (i.e., “;”), keep calling SysLib.join( ) 
                    }
                    first = i + 1; // go on to the next command delimited by “;” or “&”
                }
            }
        }
    }

Lecture 5 2023-01-17

Class Vs Interface

Why use runnable vs thread?
With runnable, it's more scalable, and you need to implement by yourself

Benefits of multithreading

  1. Responsiveness
  2. Deadlock avoidance
  3. Scalability, (utilization of multiprocess architecture)
  4. Resource sharing and economy

Responsiveness

Pasted image 20230117141629.png

Resource Sharing

Process Threads
CPU Registers Independent Independent
Memory Space Independent Sharing text and heap
File/IO descriptors Shared between a paretn and its child Shared among threads

Benefit 3: Economy

Processes Threads
Page table Independent Shared
Memory Space Copy on Write Shared Except Stack
Creation Heavy Light
TLB Necessary to flush Shared
Memory accesses at the begging DRAM X 2 TLB
Context Switch Slow Fast

Benefit 4: Utilization of multicore multiprocessor architecture

Pasted image 20230117142434.png

### User and Kernel Threads - User Threads - thread management done by user level threads library - Examples - POSIX Pthreads - Win32 Threads - Java Threads - Kernel does not care how many threads exist - Kernel Threads - Supported by the kernel - Examples - Linux - Windows XP/2000 -Solaris lightweight processes

Many-to-one Model

Many threads mapped to a single kernel thread
Pasted image 20230117142624.png
Advantage: Fast
Disadvantage: 1. Non preemption of very complicated to handle preemption and I/O, cannot utilize multiprocessor architecture

One-to-One Model

Many-to-Many Model

-covering the shortage of the previous two models
Examples:
- Window XP's fiber library
- AIX Pthreads

Pasted image 20230117143420.png

Process Structure

Thread Structures

Note

Light weight process is the same as kernel thread

User Thread Emulation

setjmp() and longjmp()

Pasted image 20230117144144.png

Program 2A

Pasted image 20230117144204.png

Lecture 6 2023-01-19

From Last Lecture

setjmp(registerset) to suspend current thread
longjump(registerset) to restore

Thread Private Resources:

Base pointer is the base of the current stack, stack pointer is the top

CPU Scheduling

CPU I/O Burst Cycle

Pasted image 20230119105930.png

Histogram of CPU Burst Times

Pasted image 20230118122323.png

Dispatcher

Selects from among the processes in memory that are ready to execute, and allocates the CPU to one of them. (Short-term scheduler)

CPU scheduling decisions may take place when a process:
1. Switches from running to waiting state (by sleep).
2. Switches from running to ready state (by yield).
3. Switches from waiting to ready (by an interrupt).
4. Terminates (by exit).

Scheduling under 1 and 4 is nonpreemptive.
All other scheduling is preemptive.

Preemptive scheduling is usually done by timer interrupt
10ms - 100msG

Scheduling Criteria

FCFS

Pasted image 20230119110255.png

SJF

Pasted image 20230119110312.png
Pasted image 20230119110324.png
Pasted image 20230119110334.png

SJF With Preemption is the best scheduling algorithm

Priority Scheduling

Round Robin Scheduling

Turnaround time varies with time quantum

Pasted image 20230119110644.png

HW2A Round Robin Scheduling

Pasted image 20230119110710.png

HW2A Stack Management

Pasted image 20230119110725.png

Lecture 7 2023-01-24

2A notes

Discussion

p1 wait = 0 8
p2 wait = 7.6 11.6
p3 wait = 10.6 11.6

tat ave = 10.4

sjf
p1 wait = 0 burst = 8 total 8
p3 wait = 8 burst = 1 total = 9
p2 wait = 8.6 burst = 4 total =12.6

Multilevel Queue Scheduling

Pasted image 20230124140648.png

Multilevel Feedback-Queue Scheduling

Pasted image 20230124140708.png

Cooperative Multithreading in java

A thread voluntary yielding control of the CPU is called cooperative multitasking

public void run( ) {
   while ( true ) {
      // perform a CPU-intensive task
      …
      // now yield control of the CPU
      Thread.yield( );
   }
} 

Java-based Round-Robin Scheduler

public class Scheduler extends Thread
{
   public Scheduler( ) {
      timeSlice = DEFAULTSLICE;
      queue = new CircularList( );
   }
   public Scheduler( int quantum ) {
      timeSlice = quantum;
      queue = new CircularList( );
   }
   public void addThread( Thread t ) {
      t.setPriority( 2 );
      queue.addItem( t );
   }
   private void schedulerSleep( ) {
      try {
         Thread.sleep( timeSlice );
      } catch ( InterruptedException e ) { };
   }
public void run( ) {
      Thread current;
      this.setPriority( 6 );
      while ( true ) {
         // get the next thread
         current = ( Thread )queue.getNext( );
         if ( ( current != null ) && ( current.isAlive( ) ) {
            current.setPriority( 4 );
            schedulerSleep( );
            current.setPriority( 2 );
         }
      } 
   }

   private CircularList queue;
   private int timeSlice;
   private static final int DEFAULT_TIME_SLICE=1000;
}

Test Program

public class TestScheduler
{
   public static void main( String args[] ) {
      Thread.currentThread( ).setPriority( Thread.MAX_PRIORITY );
      Scheduler CPUScheduler = new Scheduler( );
      CPUScheduler.start( );

      // uses TestThread, although this could be any Thread object.
      TestThread t1 = new TestThread( “Thread 1” );
      t1.start( );
      CPUScheduler.addThread( t1 );
      TestThread t2 = new TestThread( “Thread 2” );
      t2.start( );
      CPUScheduler.addThread( t2 );
      TestThread t3 = new TestThread( “Thread 3” );
      t3.start( );
      CPUScheduler.addThread( t3 );
   }
}

Why will this not work?

HW2B Vector Queue TCB

Pasted image 20230124141237.png

HW2B Multi-level feedback queue

Pasted image 20230124141311.png

HW2B: MFQ Algorithm

class Scheduler {
   public void run( ) {
        while ( true ) {
               for ( level = 0; level < 3; level++ ) {
                    if ( slice[level] == 0 ) {
                        if ( queue[level].size( ) == 0 )
                            continue;
                        currentTCB = ( TCB )queue[level].firstElement( );
                        break;
                    } else { // prevTCB was a previously currentTCB
                        currentTCB = prevTCB;
                        break;
                    }
                }
                if ( level == 3 )
                    continue;
                // midlle: the same as Scheduler_rr.java: delete, start, resume, sleep(500), and suspend!

                prevTCB = currentTCB;
                // If slice[level] returns back to 0, currentTCB must go to the next level or stay queue[2]!
}  }

Multiprocessor Scheduling

Multicore Processors

Pasted image 20230124141446.png

Load Balancing

Processor Affinity

Pasted image 20230124141530.png

Yarn

YARN is a cluster system job scheduler that supports Apache big-data computing tools: MapReduce, Spark, and Storm
Pasted image 20230124141557.png

Lecture 8

Revisiting bounded buffer

Pasted image 20230126144533.png

Race Condition

Pasted image 20230126144605.png

Critical Section

  1. Mutual Exclusion.  If process Pi is executing in its critical section(CS), then no other processes can be executing in their critical sections.
  2. Progress.  If no process is executing in its CS and there exist some processes that wish to enter their CS, then the selection of the processes that will enter the CS next cannot be postponed indefinitely.
  3. Bounded Waiting.  A bound must exist on the number of times that other processes are allowed to enter their CS after a process has made a request to enter its CS and before that request is granted.
    Pasted image 20230126144630.png

Progress <-> Deadlock
Bounded Waiting <-> starvation

Algorithm 1 (Yielding by turn)

public class Algorithm_1 extends MutualExclusion {
   	public Algorithm_1() {
    	turn = TURN_0;
   	}
   	public void enteringCriticalSection(int t) {
		while (turn != t)		// If it is not my turn,
			Thread.yield(); 	// I will relinquish CPU
   	}
   	public void leavingCriticalSection(int t) {
		turn = 1 - t;		// If I’m thread 0, turn will be 1, otherwise 0
   	}
   	private volatile int turn;		// turn placed in a register
}

Algorithm 2 (saying I’m using)

public class Algorithm_2 extends MutualExclusion  {
   public Algorithm_2() {
      flag[0] = false;
      flag[1] = false;
   }
   public void enteringCriticalSection(int t) {
      int other = 1 - t;		// If I am thread 0, the other is 1
      flag[t] = true;		// I declared I’ll enter CS
      while (flag[other] == true)	// If the other is in CS
         Thread.yield();		// I’ll relinquish CPU.
   }
   public void leavingCriticalSection(int t) {
       flag[t] = false;		// I declared I’m exiting from CS
   }
   private volatile boolean[] flag = new boolean[2];
}

Algorithm 3 (Mixed of 1 and 2)

ublic class Algorithm_3 extends MutualExclusion {
   public Algorithm_3( ) {
	flag[0] = false;
	flag[1] = false;
	turn = TURN_0;
   }
   public void enteringCriticalSection( int t ) {
	int other = 1 - t; 	// If I am thread 0, the other is 1
	flag[t] = true;	// I declared I’ll enter CS
	turn = other;	// Yield to another if both threads declared I’l enter CS	
	while ( ( flag[other] == true )  &&  ( turn == other )  )
		 Thread.yield();	// If the other declared and turn is in the other, wait!
     } 
   public void leavingCriticalSection( int t ) { flag[t] = false; }
   private volatile int turn; 
   private volatile boolean[] flag = new boolean[2];
}


Hardware Support

Review of System Call, Interrupt, Exceptions

Test and Set

synchronized boolean test_and_set( boolean *target ) {
  boolean rv = *target; // rv means a register value
  *target = true;
  return rv;
}

while ( true ) {
  while ( test_and_set( &lock ) )
    ; /* do nothing: someone else is locking, i.e., lock == true */
  
  /* ciritical section: I set lock = true and got in the CS */

  lock = false;
}

Lock

## Compare and Swap ```cpp int compare_and_swap( int *value, int expected, int new_value ) { int temp = *value;

if ( *value == expected )
*value = new_value;

return temp;
}

while ( true ) {
while ( compare_and_swap( &lock, 0, 1 ) != 0 )
; /* do nothing: someone else is locking, i.e., lock == 1 */

/* ciritical section: I set lock = t1 and got in the CS */

lock = 0;
}




## Mutex Locks
![Pasted image 20230126145025.png](/img/user/Reference/Attachments/Pasted%20image%2020230126145025.png)

Busy waiting or spin lock...you're checking until something is ready

## Semaphores
-   Synchronization tool that does not require busy waiting at a user level 
-   Semaphore S – integer variable
-   Two standard operations modify S: wait() and signal()
	-   Originally called P() and V()
-   Addressing the shortcoming of mutex locks 
-   Can only be accessed via two indivisible (atomic) operations
![Pasted image 20230126145059.png](/img/user/Reference/Attachments/Pasted%20image%2020230126145059.png)

Difference between Test and Set And Semaphore
- Test and set
		-lock = false - HARDWARE

-Semaphore
	- wait/signal
	-Semaphores processes will sleep and wakeup via Operating System

## Java Abstract Code with Semaphores
```java
public class Worker implements Runnable { 
   private Semaphore sem;
   private String name;
   public Worker(Semaphore sem, String name) { 
      this.sem = sem;
      this.name = name;
   }
   public void run() { 
      while (true) { 
         sem.wait();
         MutualExclusionUtilities.criticalSection(name);
         sem.signal();
         MutualExclusionUtilities.nonCriticalSection(name);
}  }  }

public class SemaphoreFactory { 
   public static void main(String args[]) { 
      Semaphore sem = new Semaphore(1);
      Thread[] bees = new Thread[5];
      for (int i = 0; i < 5; i++)
         bees[i] = new Thread(
                      new Worker(sem,
                      "Worker " + (new Integer(i)).toString() ));
      for (int i = 0; i < 5; i++)
         bees[i].start();
}  }

Pasted image 20230126145135.png

Pthread Semaphores

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <iostream>

using namespace std;
sem_t semaphore;

void *worker( void* arg ) {
  int id = *(int *)arg;
  for ( int i = 0; i < 2; i++ ) {
    sem_wait( &semaphore );
    //critical section begin
    cout << "thread " << id << ": entered ..." << endl;
    sleep( 1 );
    cout << "thread " << id << ": existing..." << endl;
    sem_post( &semaphore );
} }
//critical section end

int main( ) {
  sem_init( &semaphore, 0, 2 );
  pthread_t t[5];
  int id[5] = { 0, 1, 2, 3, 4 };

  for ( int i = 0; i < 5; i++ )
    pthread_create( &t[i], NULL, worker, (void *)&(id[i]) );
  for ( int i = 0; i < 5; i++ )
    pthread_join( t[i], NULL );
  sem_destroy( &semaphore );
  return 0;
}

Lecture 9 2023-01-31

Midterm Exam

Synchronization Examples

Monitors

Java Synchronization

public class ClassA {		           // Every object has a lock associated with it.
    public synchronized void method1( ) {  // Calling a synchronized method requires “owning” the lock.
    ….;
    // The lock is released when a thread exits the synchronized method.
    }
    public Synchronized void method2( ) { // If a calling thread does not own the lock it is placed in the entry set.
    }

Pasted image 20230131143131.png

Java Monitor

public void synchronized method1( ) { // Calling a synchronized method requires “owning” the lock.
			      // If a calling thread does not own the lock it is placed in the entry set.
    while ( condition == false )
        try {
            wait( );		      // The thread releases a lock and places itself in the wait set.
        } catch( InterruptedException e ) { }
    }
    ….;
    notify( );		       // The calling thread resumes one of threads waiting in the wait set.
}

Pasted image 20230131143202.png

Enter and Remove with Java Synchronization

Producer

Public synchronized void insert( Object item ) {
    while ( count == BUFFER_SIZE )
        try {
            wait( );
        } catch ( InterruptedException e ) { }
    }
    ++count;
    buffer[in] = item;
    in = ( in + 1 ) % BUFFER_SIZE;
    notify( );
}

Consumer

Public synchronized Object remove( ) {
    while ( count == 0 )
        try {
            wait( );
        } catch ( InterruptedException e ) { }
    }
    --count;
    item = buffer[out];
    out = ( out + 1 ) % BUFFER_SIZE;
    notify( );
    return item;
}

Thread OS

Pasted image 20230131143502.png

HW3B

public class SyncQueue {
   private QueueNode queue[];
   public SyncQueue( int condMax ) {
      // initialize queue[0] ~ queue[condMAX – 1]
   }
   public int enqueueAndSleep( int condition ) {
      // Implement the logic.
   }
   public void dequeueAndWakeup( int condition,
                                 int tid ) {
      // Implement the logic.
   }
}
public class QueueNode {
   private Vector<Integer> tidQueue;
   public QueueNode( ) {
      // initialize tidQueue;
   }
   public synchronized int sleep( ) {
      // Implement the logic.
   }
   public synchronized void wakeup( int tid ) {
      // Implement the logic.
   }
}

Classical Problem 2: The Readers-Writers Problem

Database

public class Database implements RWLock {
    public Database( ) {
        readerCount = 0;		// # readers in database access      
        dbWriting = false;		// a writer in database modification
    }
    public synchronized void acquireReadLock( ) { 
	/* A reader can start reading if dbWritng == false */  }
    public synchronized void releaseReadLock( )  { 
	/* A reader exits from database, as waking up a thread */  }
    public synchronized void acquireWriteLock( ) { 
	/* A writer can start writing if dbReading and dbWriting == false */  }
    public synchronized void releaseWriteLock( )  { 
	/* A writer can exit from database, as waking up a thread */  }
    private int readerCount; 
    private boolean dbWriting;
}

Readers

public synchronized void acquireReadLock( ) { 
    while (dbWriting == true) {	// while a writer is in DB, I have to wait.
        try {
            wait( );
        } catch (InterruptedException e) { }
    }
    ++readerCount;
}

public synchronized void releaseReadLock( ) {
    --readerCount
    if (readerCount == 0)	// if I’m the last reader, tell all others that DB has no more readers.
       notify();		// wake up someone
}

Writers

Public synchronized void ackquireWriteLock( ) {
    while (readerCount > 0 || dbWriting == true)  // while reader(s) or another write is in DB
        try {
            wait( );			// I have to wait.
        } catch ( InterruptedException e ) { }
    }
    dbWriting = true;			// Tell all others that DB is in write.
}

public syncrhonized void releaseWriteLock( ) {
    dbWriting = false;			// Tell all others that DB is no more in write
    notifyAll( );			// Wake up all others	 
}

Classical Problem 3: Dining Philosophers Problem

Pasted image 20230131144055.png

Philosopher I

while ( true ) {
			// get left chopstick
			chopStick[i].P();
			// get right chopstick
			chopStick[(i + 1) % 5].P();

			// eat for awhile
			
			//return left chopstick
			 chopStick[i].V( );
			// return right chopstick
			 chopStick[(i + 1) % 5].V( );
		
			// think for awhile
		}

Pasted image 20230131144151.png

Dining-Philosophers Problem Using A monitor

monitor DiningPhilosophers {
    int[ ] state = new int[5];
    static final int THINKING = 0;
    static final int HUNGRY = 1;
    static final int EATING = 2;
    condition[ ] self = new condition[5];
    public DiningPhilosophers {
        for ( int i = 0; i < 5; i++ )
            state[i] = THINKING;
    }
    public entry pickUp( int i ) {
        state[i] = HUNGRY;  // I got hungry
        test( i ); // can I have my left and right chopsticks?
        if (state[i] != EATING) // no, I can’t, then I should wait
        self[i].wait;
    }
public entry putDown( int i ) {
        state[i] = THINKING; // I’m stuffed and now thinking.
        // test lef and right neighbors
        test( ( i+4 ) % 5 );  // if possible, wake up my left.
        test( ( i+1 ) % 5 );  // if possible, wake up my right.
    }
    private test( int i ) {
       // if phi-i’s left is not eating, phi-i is hugry, and 
       // phi-i’s right is not eating, then phi-i can eat!
       // Wake up phi-i. 
        if ( ( state[( i+4 ) % 5 ] != EATING ) &&
            ( state[i] == HUNGRY ) &&
            ( state[( i+1 ) % 5] != EATING ) ) {
                state[i] = EATING;
                self[i].signal;
        }
    }
}

HW3A Dining Philosophers in C++

Lecture 10 2023-02-09

Reader and writer problem can lead to starvation of writer

for final review dining philosopher with monitor and semaphore

Deadlocks

Deadlock Characterizations

Pasted image 20230209170659.png

Deadlock Prevention

-Mutual exclusion: not required for sharable resources (but not work always)

Lecture 11 2023-02-14

Discussion

Memory Mapping

Address Binding

Pasted image 20230214163121.png

Logical Vs Physical Address Space

Physical address: the actual hardware memory address
Logical address: Each relocatable program assumes the starting location is always 0 and the memory space is much larger than actual memory
Pasted image 20230214164432.png

Relocation register helps map the memory and is located in MMU- memory management unit

Dynamic Loading

Dynamic Linking

Swapping

Pasted image 20230214165044.png

Contiguous Memory Allocation

Pasted image 20230214165159.png

Fixed Sized Partition

Memory is divided to fixed-size partitions
each partition is allocated to a process
IBM OS/360
Pasted image 20230214170525.png

Variable Sized Partition

Whenever one of the running processes (p8) is terminated

Dynamic Storage Allocation Problem

First Fit: allocate the first hole that is big enough (fastest search)
Best Fit: Allocate the smallest hole that is big enough; must search entire list, unless ordered by size. Produces the smallest leftover hole (best memory usage)
Worst-fit: Allocate the largest hole, must also search the entire list. Produces the largest leftover table (could be used effectively later)

First fit and best fit better than worst fit in terms of speed and storage

#Final Probably have worst fit algorithm

Lecture 12 2023-02-16

Memory management continued

Paging

Address Translation

HW2A

main()
objA = malloc(sizeof(ClassA)) //Class A *objA = new Class A;
objB = malloc(sizeof(ClassB)) //Class B *objB = new Class B
//sbrk(size) extends heap

delete objB;
//sbrk(-size)
delete objA;

Memory Management Part 2

Lecture 13 2023-02-21

Memory Management part 2
With shared pages, we just copy the page table

Two-level page-table scheme

Address-Translation Scheme

Segmentation

Segment Protection and Sharing

Segmentation with Paging

Logical / page size = page#
logical % page size = offset

Virtual Memory

Page replacement algorithm

Lecture 14 2023-02-23

Page Replacement

Too many page faults -> thrashing

Page Replacement mechanism
Pasted image 20230223155304.png

Page Replacement Algorithms

Reference string 7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7. (3 pages can be in memory) ![Pasted image 20230223160308.png](/img/user/Reference/Attachments/Pasted%20image%2020230223160308.png)

The first call is always a page fault

Lecture 14 2023-02-28

VM-2
Discussion
HW 4B
File-System interface?

Second Chance Algorithm

  1. If the next victim pointer points to a page whose reference bit = 0
    a. Replace it with a new brought-in page
  2. Otherwise, (i.e.,if the reference bit = 1), reset the bit to 0.
  3. Advance the next victim pointer.
  4. Go to 1.

Page Allocation Algorithm

Thrashing

Prevent Thrashing

Lecture 15 2023-03-02

File Concept:

fd = open('filename', r)
read(fd, buf1, 512) -> operating system read 512
read(fd, buf2, 1024) -> operating system read 1024
read(fd, buf3, 512) -> operating system read 256
read(fd,buf3,256) -> returns 0 which indicates end of file
close(fd)

File can be viewed as a bitstream(or byte stream)

There can still be internal fragmentation in file systems

In 4b we use syslib.rawread() and syslib.create() however, in the final project, we will use syslib.read()

File Concept

File Attributes

File Types

Pasted image 20230302155206.png

File Operations

Pasted image 20230302155233.png

close() is necessary to free up file pointer

Seek

Pasted image 20230302155303.png
After seek(), you have to use read(). Seek moves the file pointer

eg seek(fd,-4,2) followed by read(fd,buf,4)

Operations Performed on Directory

Single/Two-Level Directory

Pasted image 20230302162005.png

Tree Structured Directories

Pasted image 20230302162510.png

Acyclic-Graph/General Directory

Pasted image 20230302162534.png

File System Implementation

In-Memory File System Structures

Pasted image 20230302165035.png

Lecture 16 2023-03-07

File Locking

ln - s = symbolic link src object

File system implementation

Each entry in the inode direct block is 512 bytes

cut and paste to filetable.java
inode.java is done
implement filesystem.java and kernel.java

FINAL REVIEW 2023-03-09

Exam - Open Book

Test 5 should share uwb0

with open, first argument (0) is file name, and 1 is mode

first 4 bytes of super block shows total blocks
second 4 bytes shows total Inodes
first free block is the third integer

Each Inode
1 int = 4b
+3 shorts
+11shorts
14 shorts = 28bytes
therefore each inode = 32 bytes

512b/32b = 16 inodes
freelist is similar to a stack implementation (format)

superblock methods to implement

sync()
getFreeBlock
returnBlock

write means you will overwrite everything

superblock
returnblock()

Directory contains two arrays, 1, fsize and fname

The inedex corresponds to directory number
so 0 corresponds to / Fsize of 0 should be 1

File Structure Table
falloc

FIleTable.java

falloc()

Directory.java

ialloc()

File table needs synchronized