250 likes | 368 Views
CMSC421: Principles of Operating Systems. Nilanjan Banerjee. Assistant Professor, University of Maryland Baltimore County nilanb@umbc.edu http://www.csee.umbc.edu/~nilanb/teaching/421/. Principles of Operating Systems
E N D
CMSC421: Principles of Operating Systems Nilanjan Banerjee Assistant Professor, University of Maryland Baltimore County nilanb@umbc.edu http://www.csee.umbc.edu/~nilanb/teaching/421/ Principles of Operating Systems Acknowledgments: Some of the slides are adapted from Prof. Mark Corner and Prof. Emery Berger’s OS course at Umass Amherst
Announcements • Readings from Silberchatz[4th and 6thchapter]
Scheduling Many-one (Green Threads) One-one (linux) Many-many (Window-NT)
How does it work in Linux • Linux refers to them as tasks rather than threads • Thread creation is done through clone() system call • clone() allows a child task to share the address space of the parent task (process) • structtask_structpoints to process data structures (shared or unique)
When to use Threads and When to use processes • Processes or Threads • Performance? • Flexibility/Ease-of-use • Robustness • Simple Scheduling • OS has a list of Threads and schedules them similar to Processes. In Linux, threads/processes treated similarly • Chooses one of the threads and loads them to be run • Runs them for a while, runs another.
Flexibility/Ease of use? • Process are more flexible • Easy to spawn processes, I can ssh into a server and spawn a process • Can communicate over sockets= distributes across machines • Threads • Communicate using memory – must be on the same machine • Requires thread-safe code
Robustness • Process are more robust • Processes are separate or sandboxed from other processes • If one process dies, no effect on other processes • Threads • If one thread crashes, whole process terminates • Since there is sharing, there are problems with using the stack efficiently
Context Switch cost • Threads – much cheaper • Stash registers, PC (“IP”), stack pointer • Processes – above plus • Process context • TLB shootdown (later in VM lecture) • Process switches more expensive, or require long quanta
Synchronization and Concurrency • Probably the MOST important concept in OS • Lets look at a demonstration
What really happened? Count = count + 1 • load X R1 • add Y Z R1 • store Y in Mem Thread 1 executes the first two statements and is preempted… Thread 2 executes all the three statements Thread 1 returns and executes the third statement
Concurrency Terminology • Mutual exclusion (“mutex”) • prevents multiple threads from entering • Critical section • code only one thread can execute at a time • Lock • mechanism for mutual exclusion • Lock entering critical section, accessing shared data • Unlock when complete • Wait if locked • Invariant • Something that must be true
Why do we need concurrency? • Synchronization serves two purposes: • Ensure safety for shared updates • Avoid race conditions • Coordinate actions of threads • Parallel computation • Event notification • ALL interleavings must be correct • there are lots of interleavings of events • also constrain as little as possible
Locks/mutexes • Provide mutual exclusion to shared data • Two routines • acquire – wait for lock, then take it • release – unlock, wake up waiters • Rules: • Acquire lock before accessing shared data • Release lock afterwards • Lock initially released
Locks and Queueing • Acquire: • if unlocked,go in;otherwise wait in line • Release: • Unlock & leave
Synchronization and Concurrency • Demonstration on using pthread locks/mutexes
Implementing Locks • Requires hardware support (in general) • Can build on atomic operations: • Load/Store • Disable interrupts • Uniprocessors only • Test & Set, Compare & Swap
Disabling Interrupts intvalue; Queue q; FREE = 0, BUSY = 1 value = 0; q = empty; void acquire () { disable interrupts; if (value == BUSY) { add this thread to q; enable interrupts; sleep(); } else { value = BUSY; } enable interrupts; } void release () { disable interrupts; if (q not empty) { thread t = q.pop(); put t on ready queue; } value = FREE; enable interrupts; }
Lock Variants • Implementing Locks with Test and Set • Blocking Locks • Spin locks • Hybrids
Atomic Operation • But: locks are also variables, updated concurrently by multiple threads • Who locks the lock? • Answer: use hardware-level atomic operations • Test-and-set • Compare-and-swap
Test and Set semantics • What’s the effect of testAndset(value) when: • value = 0? (“unlocked”) • value = 1? (“locked”) inttestAndset (int*v) { int old = *v; *v= 1; return old; }
Blocking Locks • Suspend thread immediately • Lets scheduler execute another thread • Go to back of run queue or wait to be woken • Minimizes time spent waiting • But: always causes context switch void blockinglock (Lock& l) { while (testAndSet(l.v) == 1) { sched_yield(); } }
Spin Locks • Instead of blocking, loop until released void spinlock (Lock& l) { while (testAndSet(l.v) == 1) { ; } }
Other variants • Spin-then-yield: • Spin for some time, then yield • Fixed spin time • Exponential backoff
Safety • Locks can enforce mutual exclusion,but notorious source of errors • Failure to unlock • Double locking • Deadlock (its own lecture) • Priority inversion • not an “error” per se pthread_mutex_t l; void square (void) { pthread_mutex_lock (&l); // acquires lock // do stuff if (x == 0) { return; } else { x = x * x; } pthread_mutex_unlock (&l); }